1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head><title>C++ Standard Library Active Issues List</title></head>
<body bgcolor="#ffffff" text="#000000">
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">J16/02-0027 = WG21 N1369</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left">10 May 2002</td>
</tr>
<tr>
<td align="left">Project:</td>
<td align="left">Programming Language C++</td>
</tr>
<tr>
<td align="left">Reply to:</td>
<td align="left">Matt Austern <austern@research.att.com></td>
</tr>
</table>
<h1>C++ Standard Library Active Issues List (Revision 22)</h1>
<p>Reference ISO/IEC IS 14882:1998(E)</p>
<p>Also see:</p>
<ul>
<li>
<a href="lwg-toc.html">Table of Contents</a> for all library issues.</li>
<li>
<a href="lwg-index.html">Index by Section</a> for all library issues.</li>
<li>
<a href="lwg-status.html">Index by Status</a> for all library issues.</li>
<li><a href="lwg-defects.html">Library Defect Reports List</a></li>
<li><a href="lwg-closed.html">Library Closed Issues List</a></li>
</ul>
<p>The purpose of this document is to record the status of issues
which have come before the Library Working Group (LWG) of the ANSI
(J16) and ISO (WG21) C++ Standards Committee. Issues represent
potential defects in the ISO/IEC IS 14882:1998(E) document. Issues
are not to be used to request new features or other extensions. </p>
<p>This document contains only library issues which are actively being
considered by the Library Working Group. That is, issues which have a
status of <a href="lwg-active.html#New">New</a>, <a href="lwg-active.html#Open">Open</a>,
<a href="lwg-active.html#Ready">Ready</a>, and <a href="lwg-active.html#Review">Review</a>. See
<a href="lwg-defects.html">Library Defect Reports List</a> for issues considered defects and
<a href="lwg-closed.html">Library Closed Issues List</a> for issues considered closed.</p>
<p>The issues in these lists are not necessarily formal ISO Defect
Reports (DR's). While some issues will eventually be elevated to
official Defect Report status, other issues will be disposed of in
other ways. See <a href="#Status">Issue Status</a>.</p>
<p>This document is in an experimental format designed for both
viewing via a world-wide web browser and hard-copy printing. It
is available as an HTML file for browsing or PDF file for
printing.</p>
<p>Prior to Revision 14, library issues lists existed in two slightly
different versions; a Committee Version and a Public
Version. Beginning with Revision 14 the two versions were combined
into a single version.</p>
<p>This document includes <i>[bracketed italicized notes]</i> as a
reminder to the LWG of current progress on issues. Such notes are
strictly unofficial and should be read with caution as they may be
incomplete or incorrect. Be aware that LWG support for a particular
resolution can quickly change if new viewpoints or killer examples are
presented in subsequent discussions.</p>
<p>For the most current official version of this document see
<a href="http://www.dkuug.dk/jtc1/sc22/wg21">http://www.dkuug.dk/jtc1/sc22/wg21</a>.
Requests for further information about this document should include
the document number above, reference ISO/IEC 14882:1998(E), and be
submitted to Information Technology Industry Council (ITI), 1250 Eye
Street NW, Washington, DC 20005.</p>
<p>Public information as to how to obtain a copy of the C++ Standard,
join the standards committee, submit an issue, or comment on an issue
can be found in the C++ FAQ at <a href="http://www.research.att.com/~austern/csc/faq.html">http://www.research.att.com/~austern/csc/faq.html</a>.
Public discussion of C++ Standard related issues occurs on <a href="news:comp.std.c++">news:comp.std.c++</a>.
</p>
<p>For committee members, files available on the committee's private
web site include the HTML version of the Standard itself. HTML
hyperlinks from this issues list to those files will only work for
committee members who have downloaded them into the same disk
directory as the issues list files. </p>
<h2>Revision History</h2>
<ul>
<li>R22:
Post-Curaçao mailing. Added new issues <a href="lwg-active.html#362">362</a>-<a href="lwg-active.html#366">366</a>.
</li>
<li>R21:
Pre-Curaçao mailing. Added new issues <a href="lwg-closed.html#351">351</a>-<a href="lwg-active.html#361">361</a>.
</li>
<li>R20:
Post-Redmond mailing; reflects actions taken in Redmond. Added
new issues <a href="lwg-active.html#336">336</a>-<a href="lwg-active.html#350">350</a>, of which issues
<a href="lwg-active.html#347">347</a>-<a href="lwg-active.html#350">350</a> were added since Redmond, hence
not discussed at the meeting.
All Ready issues were moved to DR status, with the exception of issues
<a href="lwg-defects.html#284">284</a>, <a href="lwg-active.html#241">241</a>, and <a href="lwg-closed.html#267">267</a>.
Noteworthy issues discussed at Redmond include
<a href="lwg-active.html#120">120</a> <a href="lwg-active.html#202">202</a>, <a href="lwg-active.html#226">226</a>, <a href="lwg-active.html#233">233</a>,
<a href="lwg-defects.html#270">270</a>, <a href="lwg-active.html#253">253</a>, <a href="lwg-active.html#254">254</a>, <a href="lwg-active.html#323">323</a>.
</li>
<li>R19:
Pre-Redmond mailing. Added new issues
<a href="lwg-active.html#323">323</a>-<a href="lwg-defects.html#335">335</a>.
</li>
<li>R18:
Post-Copenhagen mailing; reflects actions taken in Copenhagen.
Added new issues <a href="lwg-defects.html#312">312</a>-<a href="lwg-defects.html#317">317</a>, and discussed
new issues <a href="lwg-defects.html#271">271</a>-<a href="lwg-closed.html#314">314</a>.
Changed status of issues
<a href="lwg-defects.html#103">103</a> <a href="lwg-defects.html#118">118</a> <a href="lwg-defects.html#136">136</a> <a href="lwg-defects.html#153">153</a>
<a href="lwg-defects.html#165">165</a> <a href="lwg-defects.html#171">171</a> <a href="lwg-defects.html#183">183</a> <a href="lwg-defects.html#184">184</a>
<a href="lwg-defects.html#185">185</a> <a href="lwg-defects.html#186">186</a> <a href="lwg-defects.html#214">214</a> <a href="lwg-defects.html#221">221</a>
<a href="lwg-defects.html#234">234</a> <a href="lwg-defects.html#237">237</a> <a href="lwg-defects.html#243">243</a> <a href="lwg-defects.html#248">248</a>
<a href="lwg-defects.html#251">251</a> <a href="lwg-defects.html#252">252</a> <a href="lwg-defects.html#256">256</a> <a href="lwg-defects.html#260">260</a>
<a href="lwg-defects.html#261">261</a> <a href="lwg-defects.html#262">262</a> <a href="lwg-defects.html#263">263</a> <a href="lwg-defects.html#265">265</a>
<a href="lwg-defects.html#268">268</a>
to DR.
Changed status of issues
<a href="lwg-defects.html#49">49</a> <a href="lwg-defects.html#109">109</a> <a href="lwg-defects.html#117">117</a> <a href="lwg-defects.html#182">182</a>
<a href="lwg-defects.html#228">228</a> <a href="lwg-defects.html#230">230</a> <a href="lwg-defects.html#232">232</a> <a href="lwg-defects.html#235">235</a>
<a href="lwg-defects.html#238">238</a> <a href="lwg-active.html#241">241</a> <a href="lwg-defects.html#242">242</a> <a href="lwg-defects.html#250">250</a>
<a href="lwg-defects.html#259">259</a> <a href="lwg-defects.html#264">264</a> <a href="lwg-defects.html#266">266</a> <a href="lwg-closed.html#267">267</a>
<a href="lwg-defects.html#271">271</a> <a href="lwg-defects.html#272">272</a> <a href="lwg-defects.html#273">273</a> <a href="lwg-defects.html#275">275</a>
<a href="lwg-defects.html#281">281</a> <a href="lwg-defects.html#284">284</a> <a href="lwg-defects.html#285">285</a> <a href="lwg-defects.html#286">286</a>
<a href="lwg-defects.html#288">288</a> <a href="lwg-defects.html#292">292</a> <a href="lwg-defects.html#295">295</a> <a href="lwg-defects.html#297">297</a>
<a href="lwg-defects.html#298">298</a> <a href="lwg-defects.html#301">301</a> <a href="lwg-defects.html#303">303</a> <a href="lwg-defects.html#306">306</a>
<a href="lwg-defects.html#307">307</a> <a href="lwg-defects.html#308">308</a> <a href="lwg-defects.html#312">312</a>
to Ready.
Closed issues
<a href="lwg-closed.html#111">111</a> <a href="lwg-closed.html#277">277</a> <a href="lwg-closed.html#279">279</a> <a href="lwg-closed.html#287">287</a>
<a href="lwg-closed.html#289">289</a> <a href="lwg-closed.html#293">293</a> <a href="lwg-closed.html#302">302</a> <a href="lwg-closed.html#313">313</a>
<a href="lwg-closed.html#314">314</a>
as NAD.
</li>
<li>R17:
Pre-Copenhagen mailing. Converted issues list to XML. Added proposed
resolutions for issues <a href="lwg-defects.html#49">49</a>, <a href="lwg-defects.html#76">76</a>, <a href="lwg-active.html#91">91</a>, <a href="lwg-defects.html#235">235</a>, <a href="lwg-defects.html#250">250</a>, <a href="lwg-closed.html#267">267</a>.
Added new issues <a href="lwg-active.html#278">278</a>-<a href="lwg-defects.html#311">311</a>.
</li>
<li>R16:
post-Toronto mailing; reflects actions taken in Toronto. Added new
issues <a href="lwg-defects.html#265">265</a>-<a href="lwg-closed.html#277">277</a>. Changed status of issues
<a href="lwg-defects.html#3">3</a>, <a href="lwg-defects.html#8">8</a>, <a href="lwg-defects.html#9">9</a>, <a href="lwg-defects.html#19">19</a>,
<a href="lwg-defects.html#26">26</a>, <a href="lwg-defects.html#31">31</a>, <a href="lwg-defects.html#61">61</a>,
<a href="lwg-defects.html#63">63</a>, <a href="lwg-defects.html#86">86</a>, <a href="lwg-defects.html#108">108</a>,
<a href="lwg-defects.html#112">112</a>, <a href="lwg-defects.html#114">114</a>, <a href="lwg-defects.html#115">115</a>,
<a href="lwg-defects.html#122">122</a>, <a href="lwg-defects.html#127">127</a>, <a href="lwg-defects.html#129">129</a>,
<a href="lwg-defects.html#134">134</a>, <a href="lwg-defects.html#137">137</a>, <a href="lwg-defects.html#142">142</a>,
<a href="lwg-defects.html#144">144</a>, <a href="lwg-defects.html#146">146</a>, <a href="lwg-defects.html#147">147</a>,
<a href="lwg-defects.html#159">159</a>, <a href="lwg-defects.html#164">164</a>, <a href="lwg-defects.html#170">170</a>,
<a href="lwg-defects.html#181">181</a>, <a href="lwg-defects.html#199">199</a>, <a href="lwg-defects.html#208">208</a>,
<a href="lwg-defects.html#209">209</a>, <a href="lwg-defects.html#210">210</a>, <a href="lwg-defects.html#211">211</a>,
<a href="lwg-defects.html#212">212</a>, <a href="lwg-defects.html#217">217</a>, <a href="lwg-defects.html#220">220</a>,
<a href="lwg-defects.html#222">222</a>, <a href="lwg-defects.html#223">223</a>, <a href="lwg-defects.html#224">224</a>,
<a href="lwg-defects.html#227">227</a> to "DR". Reopened issue <a href="lwg-active.html#23">23</a>. Reopened
issue <a href="lwg-active.html#187">187</a>. Changed issues <a href="lwg-closed.html#2">2</a> and
<a href="lwg-closed.html#4">4</a> to NAD. Fixed a typo in issue <a href="lwg-defects.html#17">17</a>. Fixed
issue <a href="lwg-defects.html#70">70</a>: signature should be changed both places it
appears. Fixed issue <a href="lwg-defects.html#160">160</a>: previous version didn't fix
the bug in enough places.
</li>
<li>R15:
pre-Toronto mailing. Added issues
<a href="lwg-active.html#233">233</a>-<a href="lwg-defects.html#264">264</a>. Some small HTML formatting
changes so that we pass Weblint tests.
</li>
<li>R14:
post-Tokyo II mailing; reflects committee actions taken in
Tokyo. Added issues <a href="lwg-defects.html#228">228</a> to <a href="lwg-defects.html#232">232</a>. (00-0019R1/N1242)
</li>
<li>R13:
pre-Tokyo II updated: Added issues <a href="lwg-defects.html#212">212</a> to <a href="lwg-defects.html#227">227</a>.
</li>
<li>R12:
pre-Tokyo II mailing: Added issues <a href="lwg-defects.html#199">199</a> to
<a href="lwg-defects.html#211">211</a>. Added "and paragraph 5" to the proposed resolution
of issue <a href="lwg-defects.html#29">29</a>. Add further rationale to issue
<a href="lwg-closed.html#178">178</a>.
</li>
<li>R11:
post-Kona mailing: Updated to reflect LWG and full committee actions
in Kona (99-0048/N1224). Note changed resolution of issues
<a href="lwg-closed.html#4">4</a> and <a href="lwg-defects.html#38">38</a>. Added issues <a href="lwg-closed.html#196">196</a>
to <a href="lwg-defects.html#198">198</a>. Closed issues list split into "defects" and
"closed" documents. Changed the proposed resolution of issue
<a href="lwg-closed.html#4">4</a> to NAD, and changed the wording of proposed resolution
of issue <a href="lwg-defects.html#38">38</a>.
</li>
<li>R10:
pre-Kona updated. Added proposed resolutions <a href="lwg-defects.html#83">83</a>,
<a href="lwg-defects.html#86">86</a>, <a href="lwg-active.html#91">91</a>, <a href="lwg-active.html#92">92</a>,
<a href="lwg-defects.html#109">109</a>. Added issues <a href="lwg-closed.html#190">190</a> to
<a href="lwg-defects.html#195">195</a>. (99-0033/D1209, 14 Oct 99)
</li>
<li>R9:
pre-Kona mailing. Added issues <a href="lwg-closed.html#140">140</a> to
<a href="lwg-defects.html#189">189</a>. Issues list split into separate "active" and
"closed" documents. (99-0030/N1206, 25 Aug 99)
</li>
<li>R8:
post-Dublin mailing. Updated to reflect LWG and full committee actions
in Dublin. (99-0016/N1193, 21 Apr 99)
</li>
<li>R7:
pre-Dublin updated: Added issues <a href="lwg-closed.html#130">130</a>, <a href="lwg-closed.html#131">131</a>,
<a href="lwg-defects.html#132">132</a>, <a href="lwg-defects.html#133">133</a>, <a href="lwg-defects.html#134">134</a>,
<a href="lwg-closed.html#135">135</a>, <a href="lwg-defects.html#136">136</a>, <a href="lwg-defects.html#137">137</a>,
<a href="lwg-closed.html#138">138</a>, <a href="lwg-defects.html#139">139</a> (31 Mar 99)
</li>
<li>R6:
pre-Dublin mailing. Added issues <a href="lwg-defects.html#127">127</a>, <a href="lwg-closed.html#128">128</a>,
and <a href="lwg-defects.html#129">129</a>. (99-0007/N1194, 22 Feb 99)
</li>
<li>R5:
update issues <a href="lwg-defects.html#103">103</a>, <a href="lwg-defects.html#112">112</a>; added issues
<a href="lwg-defects.html#114">114</a> to <a href="lwg-defects.html#126">126</a>. Format revisions to prepare
for making list public. (30 Dec 98)
</li>
<li>R4:
post-Santa Cruz II updated: Issues <a href="lwg-defects.html#110">110</a>,
<a href="lwg-closed.html#111">111</a>, <a href="lwg-defects.html#112">112</a>, <a href="lwg-closed.html#113">113</a> added, several
issues corrected. (22 Oct 98)
</li>
<li>R3:
post-Santa Cruz II: Issues <a href="lwg-closed.html#94">94</a> to <a href="lwg-defects.html#109">109</a>
added, many issues updated to reflect LWG consensus (12 Oct 98)
</li>
<li>R2:
pre-Santa Cruz II: Issues <a href="lwg-closed.html#73">73</a> to <a href="lwg-closed.html#93">93</a> added,
issue <a href="lwg-defects.html#17">17</a> updated. (29 Sep 98)
</li>
<li>R1:
Correction to issue <a href="lwg-defects.html#55">55</a> resolution, <a href="lwg-defects.html#60">60</a> code
format, <a href="lwg-defects.html#64">64</a> title. (17 Sep 98)
</li>
</ul>
<h2>
<a name="Status"></a>Issue Status</h2>
<p>
<b><a name="New">New</a></b> - The issue has not yet been
reviewed by the LWG. Any <b>Proposed Resolution</b> is purely a
suggestion from the issue submitter, and should not be construed as
the view of LWG.</p>
<p>
<b><a name="Open">Open</a></b> - The LWG has discussed the issue
but is not yet ready to move the issue forward. There are several
possible reasons for open status:</p>
<ul>
<li>Consensus may have not yet have been reached as to how to deal
with the issue.</li>
<li>Informal consensus may have been reached, but the LWG awaits
exact <b>Proposed Resolution</b> wording for review.</li>
<li>The LWG wishes to consult additional technical experts before
proceeding.</li>
<li>The issue may require further study.</li>
</ul>
<p>A <b>Proposed Resolution</b> for an open issue is still not be
construed as the view of LWG. Comments on the current state of
discussions are often given at the end of open issues in an italic
font. Such comments are for information only and should not be given
undue importance.</p>
<p>
<b><a name="Dup">Dup</a></b> - The LWG has reached consensus that
the issue is a duplicate of another issue, and will not be further
dealt with. A <b>Rationale</b> identifies the duplicated issue's
issue number. </p>
<p>
<b><a name="NAD">NAD</a></b> - The LWG has reached consensus that
the issue is not a defect in the Standard, and the issue is ready to
forward to the full committee as a proposed record of response. A
<b>Rationale</b> discusses the LWG's reasoning.</p>
<p>
<b><a name="Review">Review</a></b> - Exact wording of a
<b>Proposed Resolution</b> is now available for review on an issue
for which the LWG previously reached informal consensus.</p>
<p>
<b><a name="Ready">Ready</a></b> - The LWG has reached consensus
that the issue is a defect in the Standard, the <b>Proposed
Resolution</b> is correct, and the issue is ready to forward to the
full committee for further action as a Defect Report (DR).</p>
<p>
<b><a name="DR">DR</a></b> - (Defect Report) - The full J16
committee has voted to forward the issue to the Project Editor to be
processed as a Potential Defect Report. The Project Editor reviews
the issue, and then forwards it to the WG21 Convenor, who returns it
to the full committee for final disposition. This issues list
accords the status of DR to all these Defect Reports regardless of
where they are in that process.</p>
<p>
<b><a name="TC">TC</a></b> - (Technical Corrigenda) - The full
WG21 committee has voted to accept the Defect Report's Proposed
Resolution as a Technical Corrigenda. Action on this issue is thus
complete and no further action is possible under ISO rules.</p>
<p>
<b><a name="RR">RR</a></b> - (Record of Response) - The full WG21
committee has determined that this issue is not a defect in the
Standard. Action on this issue is thus complete and no further
action is possible under ISO rules.</p>
<p>
<b><a name="Future">Future</a></b> - In addition to the regular
status, the LWG believes that this issue should be revisited at the
next revision of the standard. It is usually paired with NAD.</p>
<p>Issues are always given the status of <a href="lwg-active.html#New">New</a> when
they first appear on the issues list. They may progress to
<a href="lwg-active.html#Open">Open</a> or <a href="lwg-active.html#Review">Review</a> while the LWG
is actively working on them. When the LWG has reached consensus on
the disposition of an issue, the status will then change to
<a href="lwg-active.html#Dup">Dup</a>, <a href="lwg-active.html#NAD">NAD</a>, or <a href="lwg-active.html#Ready">Ready</a> as appropriate. Once the full J16 committee votes to
forward Ready issues to the Project Editor, they are given the
status of Defect Report ( <a href="lwg-active.html#DR">DR</a>). These in turn may
become the basis for Technical Corrigenda (<a href="lwg-active.html#TC">TC</a>),
or are closed without action other than a Record of Response
(<a href="lwg-active.html#RR">RR</a> ). The intent of this LWG process is that
only issues which are truly defects in the Standard move to the
formal ISO DR status.
</p>
<h2>Active Issues</h2>
<hr>
<a name="23"><h3>23. Num_get overflow result</h3></a><p>
<b>Section:</b> 22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p>
<p>The current description of numeric input does not account for the possibility of
overflow. This is an implicit result of changing the description to rely on the definition
of scanf() (which fails to report overflow), and conflicts with the documented behavior of
traditional and current implementations. </p>
<p>Users expect, when reading a character sequence that results in a value unrepresentable
in the specified type, to have an error reported. The standard as written does not permit
this. </p>
<p><b>Further comments from Dietmar:</b></p>
<p>
I don't feel comfortable with the proposed resolution to issue 23: It
kind of simplifies the issue to much. Here is what is going on:
</p>
<p>
Currently, the behavior of numeric overflow is rather counter intuitive
and hard to trace, so I will describe it briefly:
</p>
<ul>
<li>
According to 22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>
paragraph 11 <tt>failbit</tt> is set if <tt>scanf()</tt> would
return an input error; otherwise a value is converted to the rules
of <tt>scanf</tt>.
</li>
<li>
<tt>scanf()</tt> is defined in terms of <tt>fscanf()</tt>.
</li>
<li>
<tt>fscanf()</tt> returns an input failure if during conversion no
character matching the conversion specification could be extracted
before reaching EOF. This is the only reason for <tt>fscanf()</tt>
to fail due to an input error and clearly does not apply to the case
of overflow.
</li>
<li>
Thus, the conversion is performed according to the rules of
<tt>fscanf()</tt> which basically says that <tt>strtod</tt>,
<tt>strtol()</tt>, etc. are to be used for the conversion.
</li>
<li>
The <tt>strtod()</tt>, <tt>strtol()</tt>, etc. functions consume as
many matching characters as there are and on overflow continue to
consume matching characters but also return a value identical to
the maximum (or minimum for signed types if there was a leading minus)
value of the corresponding type and set <tt>errno</tt> to <tt>ERANGE</tt>.
</li>
<li>
Thus, according to the current wording in the standard, overflows
can be detected! All what is to be done is to check <tt>errno</tt>
after reading an element and, of course, clearing <tt>errno</tt>
before trying a conversion. With the current wording, it can be
detected whether the overflow was due to a positive or negative
number for signed types.
</li>
</ul>
<p><b>Further discussion from Redmond:</b></p>
<p>The basic problem is that we've defined our behavior,
including our error-reporting behavior, in terms of C90. However,
C90's method of reporting overflow in scanf is not technically an
"input error". The <tt>strto_*</tt> functions are more precise.</p>
<p>There was general consensus that <tt>failbit</tt> should be set
upon overflow. We considered three options based on this:</p>
<ol>
<li>Set failbit upon conversion error (including overflow), and
don't store any value.</li>
<li>Set failbit upon conversion error, and also set <tt>errno</tt> to
indicated the precise nature of the error.</li>
<li>Set failbit upon conversion error. If the error was due to
overflow, store +-numeric_limits<T>::max() as an
overflow indication.</li>
</ol>
<p>Straw poll: (1) 5; (2) 0; (3) 8.</p>
<p>PJP will provide wording.</p>
<p><b>Proposed resolution:</b></p>
<hr>
<a name="44"><h3>44. Iostreams use operator== on int_type values</h3></a><p>
<b>Section:</b> 27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 6 Aug 1998</p>
<p>Many of the specifications for iostreams specify that character
values or their int_type equivalents are compared using operators ==
or !=, though in other places traits::eq() or traits::eq_int_type is
specified to be used throughout. This is an inconsistency; we should
change uses of == and != to use the traits members instead. </p>
<p><b>Proposed resolution:</b></p>
<p><i>[Kona: Nathan to supply proposed wording]</i></p>
<p><i>[
Tokyo: the LWG reaffirmed that this is a defect, and requires careful
review of clause 27 as the changes are context sensitive.
]</i></p>
<hr>
<a name="91"><h3>91. Description of operator>> and getline() for string<> might cause endless loop</h3></a><p>
<b>Section:</b> 21.3.7.9 <a href="lib-strings.html#lib.string.io"> [lib.string.io]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p>
<p>Operator >> and getline() for strings read until eof()
in the input stream is true. However, this might never happen, if the
stream can't read anymore without reaching EOF. So shouldn't it be
changed into that it reads until !good() ? </p>
<p><b>Proposed resolution:</b></p>
<p>In 21.3.7.9 <a href="lib-strings.html#lib.string.io"> [lib.string.io]</a>, paragraph 1, replace:</p>
<blockquote>
Effects: Begins by constructing a sentry object k as if k were
constructed by typename basic_istream<charT,traits>::sentry k( is). If
bool( k) is true, it calls str.erase() and then extracts characters
from is and appends them to str as if by calling str.append(1, c). If
is.width() is greater than zero, the maximum number n of characters
appended is is.width(); otherwise n is str.max_size(). Characters are
extracted and appended until any of the following occurs:
</blockquote>
<p>with:</p>
<blockquote>
Effects: Behaves as a formatted input function (27.6.1.2.1 <a href="lib-iostreams.html#lib.istream.formatted.reqmts"> [lib.istream.formatted.reqmts]</a>). After constructing a sentry object, if the
sentry converts to true, calls str.erase() and then extracts
characters from is and appends them to str as if by calling
str.append(1,c). If is.width() is greater than zero, the maximum
number n of characters appended is is.width(); otherwise n is
str.max_size(). Characters are extracted and appended until any of the
following occurs:
</blockquote>
<p>In 21.3.7.9 <a href="lib-strings.html#lib.string.io"> [lib.string.io]</a>, paragraph 6, replace</p>
<blockquote>
Effects: Begins by constructing a sentry object k as if by typename
basic_istream<charT,traits>::sentry k( is, true). If bool( k) is true,
it calls str.erase() and then extracts characters from is and appends
them to str as if by calling str.append(1, c) until any of the
following occurs:
</blockquote>
<p>with:</p>
<blockquote>
Effects: Behaves as an unformatted input function (27.6.1.3 <a href="lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a>), except that it does not affect the value returned
by subsequent calls to basic_istream<>::gcount(). After
constructing a sentry object, if the sentry converts to true, calls
str.erase() and then extracts characters from is and appends them to
str as if by calling str.append(1,c) until any of the following
occurs:
</blockquote>
<p><i>[Redmond: Made changes in proposed resolution. <tt>operator>></tt>
should be a formatted input function, not an unformatted input function.
<tt>getline</tt> should not be required to set <tt>gcount</tt>, since
there is no mechanism for <tt>gcount</tt> to be set except by one of
<tt>basic_istream</tt>'s member functions.]</i></p>
<p><i>[Curaçao: Nico agrees with proposed resolution.]</i></p>
<p><b>Rationale:</b></p>
<p>The real issue here is whether or not these string input functions
get their characters from a streambuf, rather than by calling an
istream's member functions, a streambuf signals failure either by
returning eof or by throwing an exception; there are no other
possibilities. The proposed resolution makes it clear that these two
functions do get characters from a streambuf.</p>
<hr>
<a name="92"><h3>92. Incomplete Algorithm Requirements</h3></a><p>
<b>Section:</b> 25 <a href="lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Nico Josuttis <b>Date:</b> 29 Sep 1998</p>
<p>The standard does not state, how often a function object is copied,
called, or the order of calls inside an algorithm. This may lead to
surprising/buggy behavior. Consider the following example: </p>
<pre>class Nth { // function object that returns true for the nth element
private:
int nth; // element to return true for
int count; // element counter
public:
Nth (int n) : nth(n), count(0) {
}
bool operator() (int) {
return ++count == nth;
}
};
....
// remove third element
list<int>::iterator pos;
pos = remove_if(coll.begin(),coll.end(), // range
Nth(3)), // remove criterion
coll.erase(pos,coll.end()); </pre>
<p>This call, in fact removes the 3rd <b>AND the 6th</b> element. This
happens because the usual implementation of the algorithm copies the
function object internally: </p>
<pre>template <class ForwIter, class Predicate>
ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op)
{
beg = find_if(beg, end, op);
if (beg == end) {
return beg;
}
else {
ForwIter next = beg;
return remove_copy_if(++next, end, beg, op);
}
} </pre>
<p>The algorithm uses find_if() to find the first element that should
be removed. However, it then uses a copy of the passed function object
to process the resulting elements (if any). Here, Nth is used again
and removes also the sixth element. This behavior compromises the
advantage of function objects being able to have a state. Without any
cost it could be avoided (just implement it directly instead of
calling find_if()). </p>
<p><b>Proposed resolution:</b></p>
<p> In [lib.function.objects] 20.3 Function objects add as new
paragraph 6 (or insert after paragraph 1): </p>
<p>Option 1: </p>
<blockquote>
Predicates are functions or function objects that fulfill the
following requirements:<br> - They return a Boolean value (bool
or a value convertible to bool)<br> - It doesn't matter for the
behavior of a predicate how often it is copied or assigned and how
often it is called.
</blockquote>
<p>Option 2: </p>
<blockquote>
- if it's a function:<br> - All calls with the same
argument values yield the same result.<br> - if it's a function
object:<br> - In any sequence of calls to operator () without
calling any non-constant member function, all calls with the same
argument values yield the same result. <br> - After an assignment
or copy both objects return the same result for the same values.
</blockquote>
<p><i>[Santa Cruz: The LWG believes that there may be more to this than
meets the eye. It applies to all function objects, particularly
predicates. Two questions: (1) must a function object be
copyable? (2) how many times is a function object called? These
are in effect questions about state. Function objects appear to
require special copy semantics to make state work, and may fail if
calling alters state and calling occurs an unexpected number of
times.]</i></p>
<p><i>[Dublin: Pete Becker felt that this may not be a defect,
but rather something that programmers need to be educated about.
There was discussion of adding wording to the effect that the number
and order of calls to function objects, including predicates, not
affect the behavior of the function object.]</i></p>
<p><i>[Pre-Kona: Nico comments: It seems the problem is that we don't
have a clear statement of "predicate" in the
standard. People including me seemed to think "a function
returning a Boolean value and being able to be called by an STL
algorithm or be used as sorting criterion or ... is a
predicate". But a predicate has more requirements: It should
never change its behavior due to a call or being copied. IMHO we have
to state this in the standard. If you like, see section 8.1.4 of my
library book for a detailed discussion.]</i></p>
<p><i>[Kona: Nico will provide wording to the effect that "unless
otherwise specified, the number of copies of and calls to function
objects by algorithms is unspecified". Consider placing in
25 <a href="lib-algorithms.html#lib.algorithms"> [lib.algorithms]</a> after paragraph 9.]</i></p>
<p><i>[Pre-Tokyo: Angelika Langer comments: if the resolution is
that algorithms are free to copy and pass around any function objects,
then it is a valid question whether they are also allowed to change
the type information from reference type to value type.]</i></p>
<p><i>[Tokyo: Nico will discuss this further with Matt as there are
multiple problems beyond the underlying problem of no definition of
"Predicate".]</i></p>
<p><i>[Post-Tokyo: Nico provided the above proposed
resolutions.]</i></p>
<p><i>[Curaçao: Nico will provide wording to make options clearer: are
the exclusive, or is one a superset of the other?]</i></p>
<hr>
<a name="96"><h3>96. Vector<bool> is not a container</h3></a><p>
<b>Section:</b> 23.2.5 <a href="lib-containers.html#lib.vector.bool"> [lib.vector.bool]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p>
<p>
<tt>vector<bool></tt> is not a container as its reference and
pointer types are not references and pointers. </p>
<p>Also it forces everyone to have a space optimization instead of a
speed one.</p>
<p>
<b>See also:</b> 99-0008 == N1185 Vector<bool> is
Nonconforming, Forces Optimization Choice.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[In Santa Cruz the LWG felt that this was Not A Defect.]</i></p>
<p><i>[In Dublin many present felt that failure to meet Container
requirements was a defect. There was disagreement as to whether
or not the optimization requirements constituted a defect.]</i></p>
<p><i>[The LWG looked at the following resolutions in some detail:
<br>
* Not A Defect.<br>
* Add a note explaining that vector<bool> does not meet
Container requirements.<br>
* Remove vector<bool>.<br>
* Add a new category of container requirements which
vector<bool> would meet.<br>
* Rename vector<bool>.<br>
<br>
No alternative had strong, wide-spread, support and every alternative
had at least one "over my dead body" response.<br>
<br>
There was also mention of a transition scheme something like (1) add
vector_bool and deprecate vector<bool> in the next standard. (2)
Remove vector<bool> in the following standard.]</i></p>
<p><i>[Modifying container requirements to permit returning proxies
(thus allowing container requirements conforming vector<bool>)
was also discussed.]</i></p>
<p><i>[It was also noted that there is a partial but ugly workaround in
that vector<bool> may be further specialized with a customer
allocator.]</i></p>
<p><i>[Kona: Herb Sutter presented his paper J16/99-0035==WG21/N1211,
vector<bool>: More Problems, Better Solutions. Much discussion
of a two step approach: a) deprecate, b) provide replacement under a
new name. LWG straw vote on that: 1-favor, 11-could live with, 2-over
my dead body. This resolution was mentioned in the LWG report to the
full committee, where several additional committee members indicated
over-my-dead-body positions.]</i></p>
<p><i>[Tokyo: Not discussed by the full LWG; no one claimed new
insights and so time was more productively spent on other issues. In
private discussions it was asserted that requirements for any solution
include 1) Increasing the full committee's understanding of the
problem, and 2) providing compiler vendors, authors, teachers, and of
course users with specific suggestions as to how to apply the eventual
solution.]</i></p>
<hr>
<a name="98"><h3>98. Input iterator requirements are badly written</h3></a><p>
<b>Section:</b> 24.1.1 <a href="lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> AFNOR <b>Date:</b> 7 Oct 1998</p>
<p>Table 72 in 24.1.1 <a href="lib-iterators.html#lib.input.iterators"> [lib.input.iterators]</a> specifies semantics for
<tt>*r++</tt> of:</p>
<p> <tt>{ T tmp = *r; ++r; return tmp; }</tt>
</p>
<p>There are two problems with this. First, the return type is
specified to be "T", as opposed to something like "convertible to T".
This is too specific: we want to allow *r++ to return an lvalue.</p>
<p>Second, writing the semantics in terms of code misleadingly
suggests that the effects *r++ should precisely replicate the behavior
of this code, including side effects. (What if it's a user-defined
type whose copy constructor has observable behavior?) We should
replace the code with words, or else put some blanket statement in
clause 17 saying that code samples aren't intended to specify exactly
how many times a copy constructor is called, even if the copy
constructor has observable behavior. (See issue <a href="lwg-active.html#334">334</a>
for a similar problem.)</p>
<p><i>[Issue still isn't clear. Matt will try to explain it more
clearly at the next meeting.]</i></p>
<p><b>Proposed resolution:</b></p>
<hr>
<a name="120"><h3>120. Can an implementor add specializations?</h3></a><p>
<b>Section:</b> 17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998</p>
<p>The original issue asked whether a library implementor could
specialize standard library templates for built-in types. (This was
an issue because users are permitted to explicitly instantiate
standard library templates.)</p>
<p>Specializations are no longer a problem, because of the resolution
to core issue 259. Under the proposed resolution, it will be legal
for a translation unit to contain both a specialization and an
explicit instantiation of the same template, provided that the
specialization comes first. In such a case, the explicit
instantiation will be ignored. Further discussion of library issue
120 assumes that the core 259 resolution will be adopted.</p>
<p>However, as noted in lib-7047, one piece of this issue still
remains: what happens if a standard library implementor explicitly
instantiates a standard library templates? It's illegal for a program
to contain two different explicit instantiations of the same template
for the same type in two different translation units (ODR violation),
and the core working group doesn't believe it is practical to relax
that restriction.</p>
<p>The issue, then, is: are users allowed to implicitly instantiate
standard library templates for non-user defined types? The status quo
answer is 'yes'. Changing it to 'no' would give library implementors
more freedom.</p>
<p>This is an issue because, for performance reasons, library
implementors often need to explicitly instantiate standard library
templates. (for example, std::basic_string<char>) Does giving
users freedom to explicitly instantiate standard library templates for
non-user defined types make it impossible or painfully difficult for
library implementors to do this?</p>
<p>John Spicer suggests, in lib-8957, that library implementors have a
mechanism they can use for explicit instantiations that doesn't
prevent users from performing their own explicit instantiations: put
each explicit instantiation in its own object file. (Different
solutions might be necessary for Unix DSOs or MS-Windows DLLs.) On
some platforms, library implementors might not need to do anything
special: the "undefined behavior" that results from having two
different explicit instantiations might be harmless.</p>
<p><b>Proposed resolution:</b></p>
<p>Option 1.</p>
<blockquote>
<p>Append to 17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> paragraph 1: </p>
<blockquote>
A program may explicitly instantiate any templates in the standard
library only if the declaration depends on a user-defined name of
external linkage and the instantiation meets the standard library
requirements for the original template.
</blockquote>
</blockquote>
<p>Option 2.</p>
<blockquote>
<p>In light of the resolution to core issue 259, no normative changes
in the library clauses are necessary. Add the following non-normative
note to the end of 17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> paragraph 1:</p>
<blockquote>
[<i>Note:</i> A program may explicitly instantiate standard library
templates, even when an explicit instantiation does not depend on
a user-defined name. <i>--end note</i>]
</blockquote>
</blockquote>
<p><i>[Copenhagen: LWG discussed three options. (1) Users may not
explicitly instantiate standard library templates, except on
user-defined types. Consequence: library implementors may freely
specialize or instantiate templates. (2) Users may explicitly
instantiate any standard library template. Consequence: if
implementors specialize or instantiate library templates, they may
need to take special steps to make sure users can do it too. (3) It
is implementation defined whether users may explicitly instantiate
standard library templates on non-user-defined types. Consequence:
library implementors may freely specialize or instantiate templates,
but may need to document some or all templates that have been
explicitly instantiated.
]</i></p>
<p><i>[Straw poll (first number is favor, second is strongly oppose): 1
- 4, 0; 2 - 9, 1; 3 - 0, 9. (Proposed resolution 1 was the original
proposed resolution.) Because there was no support for option 3, no
wording is provided.]</i></p>
<p><i>[Redmond: discussed again; straw poll had results similar to
those of Copenhagen (1 - 1, 3; 2 - 8, 4; 3 - 6, 2). Most people said
they could live with any option. The only objection to option 2 is
potential implementation difficulty. Steve Clamage volunteered do a
survey to see if there are any popular platforms where option 2 would
present a real problem for implementors. See his reflector message,
c++std-lib-9002.
]</i></p>
<p><i>[Steve and Pete Becker will talk to Jonathan Caves. The
Microsoft linker might present a problem if there are multiple copies,
some of which have static data and some of which are in DLLs. There
may be similar problems with the Apple linker; Matt will clarify
that.]</i></p>
<hr>
<a name="123"><h3>123. Should valarray helper arrays fill functions be const?</h3></a><p>
<b>Section:</b> 26.3.5.4 <a href="lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a>, 26.3.7.4 <a href="lib-numerics.html#lib.gslice.array.fill"> [lib.gslice.array.fill]</a>, 26.3.8.4 <a href="lib-numerics.html#lib.mask.array.fill"> [lib.mask.array.fill]</a>, 26.3.9.4 <a href="lib-numerics.html#lib.indirect.array.fill"> [lib.indirect.array.fill]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 15 Dec 1998 </p>
<p>One of the operator= in the valarray helper arrays is const and one
is not. For example, look at slice_array. This operator= in Section
26.3.5.2 <a href="lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a> is const: </p>
<p> <tt>void operator=(const valarray<T>&) const;</tt> </p>
<p>but this one in Section 26.3.5.4 <a href="lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a> is not: </p>
<p> <tt>void operator=(const T&); </tt>
</p>
<p>The description of the semantics for these two functions is similar. </p>
<p><b>Proposed resolution:</b></p>
<p>26.3.5 <a href="lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a> Template class slice_array</p>
<blockquote>
<p>In the class template definition for slice_array, replace the member
function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>with</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.5.4 <a href="lib-numerics.html#lib.slice.arr.fill"> [lib.slice.arr.fill]</a> slice_array fill function</p>
<blockquote>
<p>Change the function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>to</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.7 <a href="lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a> Template class gslice_array</p>
<blockquote>
<p>In the class template definition for gslice_array, replace the member
function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>with</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.7.4 <a href="lib-numerics.html#lib.gslice.array.fill"> [lib.gslice.array.fill]</a> gslice_array fill function</p>
<blockquote>
<p>Change the function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>to</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.8 <a href="lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a> Template class mask_array</p>
<blockquote>
<p>In the class template definition for mask_array, replace the member
function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>with</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.8.4 <a href="lib-numerics.html#lib.mask.array.fill"> [lib.mask.array.fill]</a> mask_array fill function</p>
<blockquote>
<p>Change the function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>to</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.9 <a href="lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a> Template class indirect_array</p>
<blockquote>
<p>In the class template definition for indirect_array, replace the member
function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>with</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p>26.3.9.4 <a href="lib-numerics.html#lib.indirect.array.fill"> [lib.indirect.array.fill]</a> indirect_array fill function</p>
<blockquote>
<p>Change the function declaration</p>
<pre>
void operator=(const T&);
</pre>
<p>to</p>
<pre>
void operator=(const T&) const;
</pre>
</blockquote>
<p><i>[Redmond: Robert provided wording.]</i></p>
<p><b>Rationale:</b></p>
<p>There's no good reason for one version of operator= being const and
another one not. Because of issue <a href="lwg-active.html#253">253</a>, this now
matters: these functions are now callable in more circumstances. In
many existing implementations, both versions are already const.</p>
<hr>
<a name="167"><h3>167. Improper use of <tt>traits_type::length()</tt>
</h3></a><p>
<b>Section:</b> 27.6.2.5.4 <a href="lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 20 Jul 1999</p>
<p>Paragraph 4 states that the length is determined using
<tt>traits::length(s)</tt>. Unfortunately, this function is not
defined for example if the character type is <tt>wchar_t</tt> and the
type of <tt>s</tt> is <tt>char const*</tt>. Similar problems exist if
the character type is <tt>char</tt> and the type of <tt>s</tt> is
either <tt>signed char const*</tt> or <tt>unsigned char
const*</tt>.</p>
<p><b>Proposed resolution:</b></p>
<p>Change 27.6.2.5.4 <a href="lib-iostreams.html#lib.ostream.inserters.character"> [lib.ostream.inserters.character]</a> paragraph 4 from:</p>
<blockquote>
<p>Effects: Behaves like an formatted inserter (as described in
lib.ostream.formatted.reqmts) of out. After a sentry object is
constructed it inserts characters. The number of characters starting
at s to be inserted is traits::length(s). Padding is determined as
described in lib.facet.num.put.virtuals. The traits::length(s)
characters starting at s are widened using out.widen
(lib.basic.ios.members). The widened characters and any required
padding are inserted into out. Calls width(0).</p>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Behaves like an formatted inserter (as described in
lib.ostream.formatted.reqmts) of out. After a sentry object is
constructed it inserts characters. The number len of characters
starting at s to be inserted is</p>
<p>
- traits::length((const char*)s) if the second argument is of type
const charT*<br>
- char_traits<char>::length(s) if the second argument is of
type const char*, const signed char*, or const unsigned char* and
and charT is not char.<br>
</p>
<p>Padding is determined as described in
lib.facet.num.put.virtuals. The len characters starting at s are
widened using out.widen (lib.basic.ios.members). The widened
characters and any required padding are inserted into out. Calls
width(0).</p>
</blockquote>
<p><i>[Kona: It is clear to the LWG there is a defect here.
Dietmar will supply specific wording.]</i></p>
<p><i>[Post-Tokyo: Dietmar supplied the above wording.]</i></p>
<p><i>[Toronto: The original proposed resolution involved
char_traits<signed char> and char_traits<unsigned char>.
There was strong opposition to requiring that library implementors
provide those specializations of char_traits.]</i></p>
<p><i>[Copenhagen: This still isn't quite right: proposed resolution
text got garbled when the signed char/unsigned char specializations
were removed. Dietmar will provide revised wording.]</i></p>
<hr>
<a name="179"><h3>179. Comparison of const_iterators to iterators doesn't work</h3></a><p>
<b>Section:</b> 23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Judy Ward <b>Date:</b> 2 Jul 1998</p>
<p>Currently the following will not compile on two well-known standard
library implementations:</p>
<blockquote>
<pre>#include <set>
using namespace std;
void f(const set<int> &s)
{
set<int>::iterator i;
if (i==s.end()); // s.end() returns a const_iterator
}</pre>
</blockquote>
<p>
The reason this doesn't compile is because operator== was implemented
as a member function of the nested classes set:iterator and
set::const_iterator, and there is no conversion from const_iterator to
iterator. Surprisingly, (s.end() == i) does work, though, because of
the conversion from iterator to const_iterator.
</p>
<p>
I don't see a requirement anywhere in the standard that this must
work. Should there be one? If so, I think the requirement would need
to be added to the tables in section 24.1.1. I'm not sure about the
wording. If this requirement existed in the standard, I would think
that implementors would have to make the comparison operators
non-member functions.</p>
<p>This issues was also raised on comp.std.c++ by Darin
Adler. The example given was:</p>
<blockquote>
<pre>bool check_equal(std::deque<int>::iterator i,
std::deque<int>::const_iterator ci)
{
return i == ci;
}</pre>
</blockquote>
<p>Comment from John Potter:</p>
<blockquote>
<p>
In case nobody has noticed, accepting it will break reverse_iterator.
</p>
<p>
The fix is to make the comparison operators templated on two types.
</p>
<pre>
template <class Iterator1, class Iterator2>
bool operator== (reverse_iterator<Iterator1> const& x,
reverse_iterator<Iterator2> const& y);
</pre>
<p>
Obviously: return x.base() == y.base();
</p>
<p>
Currently, no reverse_iterator to const_reverse_iterator compares are
valid.
</p>
<p>
BTW, I think the issue is in support of bad code. Compares should be
between two iterators of the same type. All std::algorithms require
the begin and end iterators to be of the same type.
</p>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p>Insert this paragraph after 23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> paragraph 7:</p>
<blockquote>
<p>In the expressions</p>
<pre>
i == j
i != j
i < j
i <= j
i >= j
i > j
i - j
</pre>
<p>Where i and j denote objects of a container's iterator type,
either or both may be replaced by an object of the container's
const_iterator type referring to the same element with no
change in semantics.</p>
</blockquote>
<p><i>[post-Toronto: Judy supplied a proposed resolution saying that
<tt>iterator</tt> and <tt>const_iterator</tt> could be freely mixed in
iterator comparison and difference operations.]</i></p>
<p><i>[Redmond: Dave and Howard supplied a new proposed resolution which
explicitly listed expressions; there was concern that the previous
proposed resolution was too informal.]</i></p>
<p><b>Rationale:</b></p>
<p>
The LWG believes it is clear that the above wording applies only to
the nested types <tt>X::iterator</tt> and <tt>X::const_iterator</tt>,
where <tt>X</tt> is a container. There is no requirement that
<tt>X::reverse_iterator</tt> and <tt>X::const_reverse_iterator</tt>
can be mixed. If mixing them is considered important, that's a
separate issue. (Issue <a href="lwg-active.html#280">280</a>.)
</p>
<hr>
<a name="187"><h3>187. iter_swap underspecified</h3></a><p>
<b>Section:</b> 25.2.2 <a href="lib-algorithms.html#lib.alg.swap"> [lib.alg.swap]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 14 Aug 1999</p>
<p>The description of iter_swap in 25.2.2 paragraph 7,says that it ``exchanges the values''
of the objects to which two iterators refer.<br>
<br>
What it doesn't say is whether it does so using swap or using the assignment operator and copy constructor.<br>
<br>
This question is an important one to answer, because swap is specialized to work efficiently for standard containers.<br>
For example:</p>
<blockquote>
<pre>vector<int> v1, v2;
iter_swap(&v1, &v2);</pre>
</blockquote>
<p>Is this call to iter_swap equivalent to calling swap(v1, v2)? Or is it equivalent to</p>
<blockquote>
<pre>{
vector<int> temp = v1;
v1 = v2;
v2 = temp;
}</pre>
</blockquote>
<p>The first alternative is O(1); the second is O(n).</p>
<p>A LWG member, Dave Abrahams, comments:</p>
<blockquote>
<p>Not an objection necessarily, but I want to point out the cost of that requirement:</p>
<blockquote>
<p><tt>iter_swap(list<T>::iterator, list<T>::iterator)</tt></p>
</blockquote>
<p>can currently be specialized to be more efficient than iter_swap(T*,T*) for many T (by using splicing). Your proposal would make that optimization
illegal. </p>
</blockquote>
<p><i>[Kona: The LWG notes the original need for iter_swap was proxy iterators
which are no longer permitted.]</i></p>
<p><b>Proposed resolution:</b></p>
<p>Change the effect clause of iter_swap in 25.2.2 paragraph 7 from:</p>
<blockquote>
<p>Exchanges the values pointed to by the two iterators a and b.</p>
</blockquote>
<p>to</p>
<blockquote>
<p>
<tt>swap(*a, *b)</tt>.</p>
</blockquote>
<p><i>[post-Toronto: The LWG is concerned about possible
overspecification: there may be cases, such as Dave Abrahams's example
above, and such as vector<bool>'s iterators, where it makes more
sense for iter_swap to do something other than swap. If performance
is a concern, it may be better to have explicit complexity
requirements than to say how iter_swap should be implemented.]</i></p>
<p><i>[Redmond: Discussed, with no consensus. There was very little
support for the proposed resolution. Some people favored closing this
issue as NAD. Others favored a more complicated specification of
<tt>iter_swap</tt>, which might distinguish between ordinary iterators
and proxies. A possible new issue: how do we know that the iterators
passed to <tt>iter_swap</tt> have Assignable value types? (If this
new issue is real, it extends far beyond just
<tt>iter_swap</tt>.)]</i></p>
<hr>
<a name="197"><h3>197. max_size() underspecified</h3></a><p>
<b>Section:</b> 20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>, 23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 21 Oct 1999</p>
<p>Must the value returned by max_size() be unchanged from call to call? </p>
<p>Must the value returned from max_size() be meaningful? </p>
<p>Possible meanings identified in lib-6827: </p>
<p>1) The largest container the implementation can support given "best
case" conditions - i.e. assume the run-time platform is "configured to
the max", and no overhead from the program itself. This may possibly
be determined at the point the library is written, but certainly no
later than compile time.<br>
<br>
2) The largest container the program could create, given "best case"
conditions - i.e. same platform assumptions as (1), but take into
account any overhead for executing the program itself. (or, roughly
"storage=storage-sizeof(program)"). This does NOT include any resource
allocated by the program. This may (or may not) be determinable at
compile time.<br>
<br>
3) The largest container the current execution of the program could
create, given knowledge of the actual run-time platform, but again,
not taking into account any currently allocated resource. This is
probably best determined at program start-up.<br>
<br>
4) The largest container the current execution program could create at
the point max_size() is called (or more correctly at the point
max_size() returns :-), given it's current environment (i.e. taking
into account the actual currently available resources). This,
obviously, has to be determined dynamically each time max_size() is
called. </p>
<p><b>Proposed resolution:</b></p>
<p>Change 20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> table 32 max_size() wording from:<br>
<br>
the largest value that can meaningfully be
passed to X::allocate<br>
to:<br>
the value of the largest constant expression
(5.19 <a href="expr.html#expr.const"> [expr.const]</a>) that could ever meaningfully be passed to X::allocate</p>
<p>
Change 23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> table 65 max_size() wording from:<br>
<br>
size() of the largest possible container.<br>
to:<br>
the value of the largest constant expression
(5.19 <a href="expr.html#expr.const"> [expr.const]</a>) that could ever meaningfully be returned by X::size().
</p>
<p><i>[Kona: The LWG informally discussed this and asked Andy Sawyer to submit
an issue.]</i></p>
<p><i>[Tokyo: The LWG believes (1) above is the intended meaning.]</i></p>
<p><i>[Post-Tokyo: Beman Dawes supplied the above resolution at the
request of the LWG. 21.3.3 <a href="lib-strings.html#lib.string.capacity"> [lib.string.capacity]</a> was not changed because it
references max_size() in 23.1. The term "compile-time" was
avoided because it is not defined anywhere in the standard (even
though it is used several places in the library clauses).]</i></p>
<p><i>[Copenhagen: Exactly what <tt>max_size</tt> means is still
unclear. It may have a different meaning as a container member
function than as an allocator member function. For the latter,
it is probably best thought of as an architectural limit.
Nathan will provide new wording.]</i></p>
<hr>
<a name="200"><h3>200. Forward iterator requirements don't allow constant iterators</h3></a><p>
<b>Section:</b> 24.1.3 <a href="lib-iterators.html#lib.forward.iterators"> [lib.forward.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 19 Nov 1999</p>
<p>
In table 74, the return type of the expression <tt>*a</tt> is given
as <tt>T&</tt>, where <tt>T</tt> is the iterator's value type.
For constant iterators, however, this is wrong. ("Value type"
is never defined very precisely, but it is clear that the value type
of, say, <tt>std::list<int>::const_iterator</tt> is supposed to be
<tt>int</tt>, not <tt>const int</tt>.)
</p>
<p><b>Proposed resolution:</b></p>
<p>
In table 74, in the <tt>*a</tt> and <tt>*r++</tt> rows, change the
return type from "<tt>T&</tt>" to "<tt>T&</tt>
if <tt>X</tt> is mutable, otherwise <tt>const T&</tt>".
In the <tt>a->m</tt> row, change the return type from
"<tt>U&</tt>" to "<tt>U&</tt> if <tt>X</tt> is mutable,
otherwise <tt>const U&</tt>".
</p>
<p><i>[Tokyo: The LWG believes this is the tip of a larger iceberg;
there are multiple const problems with the STL portion of the library
and that these should be addressed as a single package. Note
that issue <a href="lwg-closed.html#180">180</a> has already been declared NAD Future for
that very reason.]</i></p>
<p><i>[Redmond: the LWG thinks this is separable from other constness
issues. This issue is just cleanup; it clarifies language that was
written before we had iterator_traits. Proposed resolution was
modified: the original version only discussed *a. It was pointed out
that we also need to worry about *r++ and a->m.]</i></p>
<hr>
<a name="201"><h3>201. Numeric limits terminology wrong</h3></a><p>
<b>Section:</b> 18.2.1 <a href="lib-support.html#lib.limits"> [lib.limits]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Stephen Cleary <b>Date:</b> 21 Dec 1999</p>
<p>
In some places in this section, the terms "fundamental types" and
"scalar types" are used when the term "arithmetic types" is intended.
The current usage is incorrect because void is a fundamental type and
pointers are scalar types, neither of which should have
specializations of numeric_limits.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 18.2 [lib.support.limits] para 1 from:</p>
<blockquote>
<p> The headers <limits>, <climits>, and <cfloat> supply characteristics of implementation-dependent fundamental types (3.9.1).</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The headers <limits>, <climits>, and <cfloat> supply characteristics of implementation-dependent arithmetic types (3.9.1).</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 1 from:</p>
<blockquote>
<p> The numeric_limits component provides a C++ program with information about various properties of the implementation's representation of the fundamental
types.</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The numeric_limits component provides a C++ program with information about various properties of the implementation's representation of the arithmetic
types.</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 2 from:</p>
<blockquote>
<p> Specializations shall be provided for each fundamental type. . .</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> Specializations shall be provided for each arithmetic type. . .</p>
</blockquote>
<p>Change 18.2.1 [lib.limits] para 4 from:</p>
<blockquote>
<p> Non-fundamental standard types. . .</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> Non-arithmetic standard types. . .</p>
</blockquote>
<p>Change 18.2.1.1 [lib.numeric.limits] para 1 from:</p>
<blockquote>
<p> The member is_specialized makes it possible to distinguish between fundamental types, which have specializations, and non-scalar types, which
do not.</p>
</blockquote>
<p>to:</p>
<blockquote>
<p> The member is_specialized makes it possible to distinguish between arithmetic types, which have specializations, and non-arithmetic types,
which do not.</p>
</blockquote>
<p><i>[post-Toronto: The opinion of the LWG is that the wording in the
standard, as well as the wording of the proposed resolution, is
flawed. The term "arithmetic types" is well defined in C
and C++, and it is not clear that the term is being used correctly.
It is also not clear that the term "implementation
dependent" has any useful meaning in this context. The biggest
problem is that numeric_limits seems to be intended both for built-in
types and for user-defined types, and the standard doesn't make it
clear how numeric_limits applies to each of those cases. A wholesale
review of numeric_limits is needed. A paper would be welcome.]</i></p>
<hr>
<a name="202"><h3>202. unique() effects unclear when predicate not an equivalence relation</h3></a><p>
<b>Section:</b> 25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 13 Jan 2000</p>
<p>
What should unique() do if you give it a predicate that is not an
equivalence relation? There are at least two plausible answers:
</p>
<blockquote>
<p>
1. You can't, because 25.2.8 says that it it "eliminates all but
the first element from every consecutive group of equal
elements..." and it wouldn't make sense to interpret "equal" as
meaning anything but an equivalence relation. [It also doesn't
make sense to interpret "equal" as meaning ==, because then there
would never be any sense in giving a predicate as an argument at
all.]
</p>
<p>
2. The word "equal" should be interpreted to mean whatever the
predicate says, even if it is not an equivalence relation
(and in particular, even if it is not transitive).
</p>
</blockquote>
<p>
The example that raised this question is from Usenet:
</p>
<blockquote>
<pre>int f[] = { 1, 3, 7, 1, 2 };
int* z = unique(f, f+5, greater<int>());</pre>
</blockquote>
<p>
If one blindly applies the definition using the predicate
greater<int>, and ignore the word "equal", you get:
</p>
<blockquote>
<p>
Eliminates all but the first element from every consecutive group
of elements referred to by the iterator i in the range [first, last)
for which *i > *(i - 1).
</p>
</blockquote>
<p>
The first surprise is the order of the comparison. If we wanted to
allow for the predicate not being an equivalence relation, then we
should surely compare elements the other way: pred(*(i - 1), *i). If
we do that, then the description would seem to say: "Break the
sequence into subsequences whose elements are in strictly increasing
order, and keep only the first element of each subsequence". So the
result would be 1, 1, 2. If we take the description at its word, it
would seem to call for strictly DEcreasing order, in which case the
result should be 1, 3, 7, 2.<br>
<br>
In fact, the SGI implementation of unique() does neither: It yields 1,
3, 7.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> paragraph 1 to:</p>
<blockquote>
For a nonempty range, eliminates all but the first element from every
consecutive group of equivalent elements referred to by the iterator
<tt>i</tt> in the range [first+1, last) for which the following
conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) !=
false</tt>.
</blockquote>
<p>
Also insert a new paragraph, paragraph 2a, that reads: "Requires: The
comparison function must be an equivalence relation."
</p>
<p><i>[Redmond: discussed arguments for and against requiring the
comparison function to be an equivalence relation. Straw poll:
14-2-5. First number is to require that it be an equivalence
relation, second number is to explicitly not require that it be an
equivalence relation, third number is people who believe they need
more time to consider the issue. A separate issue: Andy Sawyer
pointed out that "i-1" is incorrect, since "i" can refer to the first
iterator in the range. Matt provided wording to address this
problem.]</i></p>
<p><i>[Curaçao: The LWG changed "... the range (first,
last)..." to "... the range [first+1, last)..." for
clarity. They considered this change close enough to editorial to not
require another round of review.]</i></p>
<p><b>Rationale:</b></p>
<p>The LWG also considered an alternative resolution: change
25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> paragraph 1 to:</p>
<blockquote>
For a nonempty range, eliminates all but the first element from every
consecutive group of elements referred to by the iterator
<tt>i</tt> in the range (first, last) for which the following
conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) !=
false</tt>.
</blockquote>
<p>
Also insert a new paragraph, paragraph 1a, that reads: "Notes: The
comparison function need not be an equivalence relation."
</p>
<p>Informally: the proposed resolution imposes an explicit requirement
that the comparison function be an equivalence relation. The
alternative resolution does not, and it gives enough information so
that the behavior of unique() for a non-equivalence relation is
specified. Both resolutions are consistent with the behavior of
existing implementations.</p>
<hr>
<a name="225"><h3>225. std:: algorithms use of other unqualified algorithms</h3></a><p>
<b>Section:</b> 17.4.4.3 <a href="lib-intro.html#lib.global.functions"> [lib.global.functions]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Apr 2000</p>
<p>Are algorithms in std:: allowed to use other algorithms without qualification, so functions in
user namespaces might be found through Koenig lookup?</p>
<p>For example, a popular standard library implementation includes this
implementation of std::unique:</p>
<blockquote>
<pre>namespace std {
template <class _ForwardIter>
_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
__first = adjacent_find(__first, __last);
return unique_copy(__first, __last, __first);
}
}</pre>
</blockquote>
<p>Imagine two users on opposite sides of town, each using unique on his own
sequences bounded by my_iterators . User1 looks at his standard library
implementation and says, "I know how to implement a more efficient
unique_copy for my_iterators", and writes:</p>
<blockquote>
<pre>namespace user1 {
class my_iterator;
// faster version for my_iterator
my_iterator unique_copy(my_iterator, my_iterator, my_iterator);
}</pre>
</blockquote>
<p>user1::unique_copy() is selected by Koenig lookup, as he intended.</p>
<p>User2 has other needs, and writes:</p>
<blockquote>
<pre>namespace user2 {
class my_iterator;
// Returns true iff *c is a unique copy of *a and *b.
bool unique_copy(my_iterator a, my_iterator b, my_iterator c);
}</pre>
</blockquote>
<p>User2 is shocked to find later that his fully-qualified use of
std::unique(user2::my_iterator, user2::my_iterator, user2::my_iterator) fails to
compile (if he's lucky). Looking in the standard, he sees the following Effects
clause for unique():</p>
<blockquote>
<p>Effects: Eliminates all but the first element from every consecutive group
of equal elements referred to by the iterator i in the range [first, last) for
which the following corresponding conditions hold: *i == *(i - 1) or pred(*i,
*(i - 1)) != false</p>
</blockquote>
<p>The standard gives user2 absolutely no reason to think he can interfere with
std::unique by defining names in namespace user2. His standard library has been
built with the template export feature, so he is unable to inspect the
implementation. User1 eventually compiles his code with another compiler, and
his version of unique_copy silently stops being called. Eventually, he realizes
that he was depending on an implementation detail of his library and had no
right to expect his unique_copy() to be called portably.</p>
<p>On the face of it, and given above scenario, it may seem obvious that the
implementation of unique() shown is non-conforming because it uses unique_copy()
rather than ::std::unique_copy(). Most standard library implementations,
however, seem to disagree with this notion.</p>
<p> <i>[Tokyo: Steve Adamczyk from
the core working group indicates that "std::" is sufficient;
leading "::" qualification is not required because any namespace
qualification is sufficient to suppress Koenig lookup.]</i>
</p>
<p><b>Proposed resolution:</b></p>
<p>Add a paragraph and a note at the end of
17.4.4.3 <a href="lib-intro.html#lib.global.functions"> [lib.global.functions]</a>:</p>
<blockquote>
<p>Unless otherwise specified, no global or non-member function in the
standard library shall use a function from another namespace which is
found through <i>argument-dependent name lookup</i> (3.4.2 <a href="basic.html#basic.lookup.koenig"> [basic.lookup.koenig]</a>).</p>
<p>[Note: the phrase "unless otherwise specified" is intended to
allow Koenig lookup in cases like that of ostream_iterators:<br>
<br>
Effects:</p>
<blockquote>
<p>*out_stream << value;<br>
if(delim != 0) *out_stream << delim;<br>
return (*this);</p>
<p>--end note]</p>
</blockquote>
</blockquote>
<p><i>[Tokyo: The LWG agrees that this is a defect in the standard, but
is as yet unsure if the proposed resolution is the best
solution. Furthermore, the LWG believes that the same problem of
unqualified library names applies to wording in the standard itself,
and has opened issue <a href="lwg-active.html#229">229</a> accordingly. Any resolution of
issue <a href="lwg-active.html#225">225</a> should be coordinated with the resolution of
issue <a href="lwg-active.html#229">229</a>.]</i></p>
<p><i>[Toronto: The LWG is not sure if this is a defect in the
standard. Most LWG members believe that an implementation of
<tt>std::unique</tt> like the one quoted in this issue is already
illegal, since, under certain circumstances, its semantics are not
those specified in the standard. The standard's description of
<tt>unique</tt> does not say that overloading <tt>adjacent_find</tt>
should have any effect.]</i></p>
<p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues
225, 226, and 229. Their conclusion was that the issues should be
separated into an LWG portion (Howard will write a proposal), and a
EWG portion (Dave will write a proposal). The LWG and EWG had
(separate) discussions of this plan the next day.]</i></p>
<hr>
<a name="226"><h3>226. User supplied specializations or overloads of namespace std function templates</h3></a><p>
<b>Section:</b> 17.4.3.1 <a href="lib-intro.html#lib.reserved.names"> [lib.reserved.names]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Apr 2000</p>
<p>The issues are: </p>
<p>1. How can a 3rd party library implementor (lib1) write a version of a standard
algorithm which is specialized to work with his own class template? </p>
<p>2. How can another library implementor (lib2) write a generic algorithm which
will take advantage of the specialized algorithm in lib1?</p>
<p>This appears to be the only viable answer under current language rules:</p>
<blockquote>
<pre>namespace lib1
{
// arbitrary-precision numbers using T as a basic unit
template <class T>
class big_num { //...
};
</pre>
<pre> // defining this in namespace std is illegal (it would be an
// overload), so we hope users will rely on Koenig lookup
template <class T>
void swap(big_int<T>&, big_int<T>&);
}</pre>
<pre>#include <algorithm>
namespace lib2
{
template <class T>
void generic_sort(T* start, T* end)
{
...
// using-declaration required so we can work on built-in types
using std::swap;
// use Koenig lookup to find specialized algorithm if available
swap(*x, *y);
}
}</pre>
</blockquote>
<p>This answer has some drawbacks. First of all, it makes writing lib2 difficult
and somewhat slippery. The implementor needs to remember to write the
using-declaration, or generic_sort will fail to compile when T is a built-in
type. The second drawback is that the use of this style in lib2 effectively
"reserves" names in any namespace which defines types which may
eventually be used with lib2. This may seem innocuous at first when applied to
names like swap, but consider more ambiguous names like unique_copy() instead.
It is easy to imagine the user wanting to define these names differently in his
own namespace. A definition with semantics incompatible with the standard
library could cause serious problems (see issue <a href="lwg-active.html#225">225</a>).</p>
<p>Why, you may ask, can't we just partially specialize std::swap()? It's
because the language doesn't allow for partial specialization of function
templates. If you write:</p>
<blockquote>
<pre>namespace std
{
template <class T>
void swap(lib1::big_int<T>&, lib1::big_int<T>&);
}</pre>
</blockquote>
<p>You have just overloaded std::swap, which is illegal under the current
language rules. On the other hand, the following full specialization is legal:</p>
<blockquote>
<pre>namespace std
{
template <>
void swap(lib1::other_type&, lib1::other_type&);
}</pre>
</blockquote>
<p>This issue reflects concerns raised by the "Namespace issue
with specialized swap" thread on comp.lang.c++.moderated. A
similar set of concerns was earlier raised on the boost.org mailing
list and the ACCU-general mailing list. Also see library reflector
message c++std-lib-7354.</p>
<p>
J. C. van Winkel points out (in c++std-lib-9565) another unexpected
fact: it's impossible to output a container of std::pair's using copy
and an ostream_iterator, as long as both pair-members are built-in or
std:: types. That's because a user-defined operator<< for (for
example) std::pair<const std::string, int> will not be found:
lookup for operator<< will be performed only in namespace std.
Opinions differed on whether or not this was a defect, and, if so,
whether the defect is that something is wrong with user-defined
functionality and std, or whether it's that the standard library does
not provide an operator<< for std::pair<>.
</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Tokyo: Summary, "There is no conforming way to extend
std::swap for user defined templates." The LWG agrees that
there is a problem. Would like more information before
proceeding. This may be a core issue. Core issue 229 has been opened
to discuss the core aspects of this problem. It was also noted that
submissions regarding this issue have been received from several
sources, but too late to be integrated into the issues list.
]</i></p>
<p><i>[Post-Tokyo: A paper with several proposed resolutions,
J16/00-0029==WG21/N1252, "Shades of namespace std functions
" by Alan Griffiths, is in the Post-Tokyo mailing. It
should be considered a part of this issue.]</i></p>
<p><i>[Toronto: Dave Abrahams and Peter Dimov have proposed a
resolution that involves core changes: it would add partial
specialization of function template. The Core Working Group is
reluctant to add partial specialization of function templates. It is
viewed as a large change, CWG believes that proposal presented leaves
some syntactic issues unanswered; if the CWG does add partial
specialization of function templates, it wishes to develop its own
proposal. The LWG continues to believe that there is a serious
problem: there is no good way for users to force the library to use
user specializations of generic standard library functions, and in
certain cases (e.g. transcendental functions called by
<tt>valarray</tt> and <tt>complex</tt>) this is important. Koenig
lookup isn't adequate, since names within the library must be
qualified with <tt>std</tt> (see issue 225), specialization doesn't
work (we don't have partial specialization of function templates), and
users aren't permitted to add overloads within namespace std.
]</i></p>
<p><i>[Copenhagen: Discussed at length, with no consensus. Relevant
papers in the pre-Copenhagen mailing: N1289, N1295, N1296. Discussion
focused on four options. (1) Relax restrictions on overloads within
namespace std. (2) Mandate that the standard library use unqualified
calls for <tt>swap</tt> and possibly other functions. (3) Introduce
helper class templates for <tt>swap</tt> and possibly other functions.
(4) Introduce partial specialization of function templates. Every
option had both support and opposition. Straw poll (first number is
support, second is strongly opposed): (1) 6, 4; (2) 6, 7; (3) 3, 8;
(4) 4, 4.]</i></p>
<p><i>[Redmond: Discussed, again no consensus. Herb presented an
argument that a user who is defining a type <tt>T</tt> with an
associated <tt>swap</tt> should not be expected to put that
<tt>swap</tt> in namespace std, either by overloading or by partial
specialization. The argument is that <tt>swap</tt> is part of
<tt>T</tt>'s interface, and thus should to in the same namespace as
<tt>T</tt> and only in that namespace. If we accept this argument,
the consequence is that standard library functions should use
unqualified call of <tt>swap</tt>. (And which other functions? Any?)
A small group (Nathan, Howard, Jeremy, Dave, Matt, Walter, Marc) will
try to put together a proposal before the next meeting.]</i></p>
<p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues
225, 226, and 229. Their conclusion was that the issues should be
separated into an LWG portion (Howard will write a proposal), and a
EWG portion (Dave will write a proposal). The LWG and EWG had
(separate) discussions of this plan the next day.]</i></p>
<hr>
<a name="229"><h3>229. Unqualified references of other library entities</h3></a><p>
<b>Section:</b> 17.4.1.1 <a href="lib-intro.html#lib.contents"> [lib.contents]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Steve Clamage <b>Date:</b> 19 Apr 2000</p>
<p>Throughout the library chapters, the descriptions of library entities refer
to other library entities without necessarily qualifying the names.</p>
<p>For example, section 25.2.2 "Swap" describes the effect of
swap_ranges in terms of the unqualified name "swap". This section
could reasonably be interpreted to mean that the library must be implemented so
as to do a lookup of the unqualified name "swap", allowing users to
override any ::std::swap function when Koenig lookup applies.</p>
<p>Although it would have been best to use explicit qualification with
"::std::" throughout, too many lines in the standard would have to be
adjusted to make that change in a Technical Corrigendum.</p>
<p>Issue <a href="lwg-defects.html#182">182</a>, which addresses qualification of
<tt>size_t</tt>, is a special case of this.
</p>
<p><b>Proposed resolution:</b></p>
<p>To section 17.4.1.1 "Library contents" Add the following paragraph:</p>
<blockquote>
<p>Whenever a name x defined in the standard library is mentioned, the name x
is assumed to be fully qualified as ::std::x, unless explicitly described
otherwise. For example, if the Effects section for library function F is
described as calling library function G, the function ::std::G is meant.</p>
</blockquote>
<p><i>[Post-Tokyo: Steve Clamage submitted this issue at the request of
the LWG to solve a problem in the standard itself similar to the
problem within implementations of library identified by issue <a href="lwg-active.html#225">225</a>. Any resolution of issue <a href="lwg-active.html#225">225</a> should be
coordinated with the resolution of this issue.]</i></p>
<p><i>[post-Toronto: Howard is undecided about whether it is
appropriate for all standard library function names referred to in
other standard library functions to be explicitly qualified by
<tt>std</tt>: it is common advice that users should define global
functions that operate on their class in the same namespace as the
class, and this requires argument-dependent lookup if those functions
are intended to be called by library code. Several LWG members are
concerned that valarray appears to require argument-dependent lookup,
but that the wording may not be clear enough to fall under
"unless explicitly described otherwise".]</i></p>
<p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues
225, 226, and 229. Their conclusion was that the issues should be
separated into an LWG portion (Howard will write a proposal), and a
EWG portion (Dave will write a proposal). The LWG and EWG had
(separate) discussions of this plan the next day.]</i></p>
<hr>
<a name="231"><h3>231. Precision in iostream?</h3></a><p>
<b>Section:</b> 22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> James Kanze, Stephen Clamage <b>Date:</b> 25 Apr 2000</p>
<p>What is the following program supposed to output?</p>
<pre>#include <iostream>
int
main()
{
std::cout.setf( std::ios::scientific , std::ios::floatfield ) ;
std::cout.precision( 0 ) ;
std::cout << 1.00 << '\n' ;
return 0 ;
}</pre>
<p>From my C experience, I would expect "1e+00"; this is what
<tt>printf("%.0e" , 1.00 );</tt> does. G++ outputs
"1.000000e+00".</p>
<p>The only indication I can find in the standard is 22.2.2.2.2/11,
where it says "For conversion from a floating-point type, if
(flags & fixed) != 0 or if str.precision() > 0, then
str.precision() is specified in the conversion specification."
This is an obvious error, however, fixed is not a mask for a field,
but a value that a multi-bit field may take -- the results of and'ing
fmtflags with ios::fixed are not defined, at least not if
ios::scientific has been set. G++'s behavior corresponds to what might
happen if you do use (flags & fixed) != 0 with a typical
implementation (floatfield == 3 << something, fixed == 1
<< something, and scientific == 2 << something).</p>
<p>Presumably, the intent is either (flags & floatfield) != 0, or
(flags & floatfield) == fixed; the first gives something more or
less like the effect of precision in a printf floating point
conversion. Only more or less, of course. In order to implement printf
formatting correctly, you must know whether the precision was
explicitly set or not. Say by initializing it to -1, instead of 6, and
stating that for floating point conversions, if precision < -1, 6
will be used, for fixed point, if precision < -1, 1 will be used,
etc. Plus, of course, if precision == 0 and flags & floatfield ==
0, 1 should be = used. But it probably isn't necessary to emulate all
of the anomalies of printf:-).</p>
<p><b>Proposed resolution:</b></p>
<p>
In 22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a>, paragraph 11, change
"if <tt>(flags & fixed) != 0</tt>" to
"if <tt>(flags & floatfield) == fixed ||
(flags & floatfield) == scientific</tt>"
</p>
<p><b>Rationale:</b></p>
<p>The floatfield determines whether numbers are formatted as if
with %f, %e, or %g. If the <tt>fixed</tt> bit is set, it's %f,
if <tt>scientific</tt> it's %e, and if both bits are set, or
neither, it's %e.</p>
<p>Turning to the C standard, a precision of 0 is meaningful
for %f and %e, but not for %g: for %g, precision 0 is taken
to be the same as precision 1.</p>
<p>The proposed resolution has the effect that the output of
the above program will be "1e+00".</p>
<p><i>[Curaçao: Howard will send Matt improved wording dealing with
case not covered by current PR.]</i></p>
<hr>
<a name="233"><h3>233. Insertion hints in associative containers</h3></a><p>
<b>Section:</b> 23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Andrew Koenig <b>Date:</b> 30 Apr 2000</p>
<p>
If <tt>mm</tt> is a multimap and <tt>p</tt> is an iterator
into the multimap, then <tt>mm.insert(p, x)</tt> inserts
<tt>x</tt> into <tt>mm</tt> with <tt>p</tt> as a hint as
to where it should go. Table 69 claims that the execution time is
amortized constant if the insert winds up taking place adjacent to
<tt>p</tt>, but does not say when, if ever, this is guaranteed to
happen. All it says it that <tt>p</tt> is a hint as to where to
insert.
</p>
<p>
The question is whether there is any guarantee about the relationship
between <tt>p</tt> and the insertion point, and, if so, what it
is.
</p>
<p>
I believe the present state is that there is no guarantee: The user
can supply <tt>p</tt>, and the implementation is allowed to
disregard it entirely.
</p>
<p>
<b>Additional comments from Nathan:</b><br>
The vote [in Redmond] was on whether to elaborately specify the use of
the hint, or to require behavior only if the value could be inserted
adjacent to the hint. I would like to ensure that we have a chance to
vote for a deterministic treatment: "before, if possible, otherwise
after, otherwise anywhere appropriate", as an alternative to the
proposed "before or after, if possible, otherwise [...]".
</p>
<p><b>Proposed resolution:</b></p>
<p>In table 69 "Associative Container Requirements" in 23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a>, in the row for <tt>a.insert(p, t)</tt>,
change</p>
<blockquote>
iterator p is a hint pointing to where the insert
should start to search.
</blockquote>
<p>to</p>
<blockquote>
insertion adjacent to iterator p is preferred if
more than one insertion point is valid.
</blockquote>
<p>and change</p>
<blockquote>
logarithmic in general, but amortized constant if
t is inserted right after p.
</blockquote>
<p>to</p>
<blockquote>
logarithmic in general, but amortized constant if
t is inserted adjacent to iterator p.
</blockquote>
<p><i>[Toronto: there was general agreement that this is a real defect:
when inserting an element x into a multiset that already contains
several copies of x, there is no way to know whether the hint will be
used. The proposed resolution was that the new element should always
be inserted as close to the hint as possible. So, for example, if
there is a subsequence of equivalent values, then providing a.begin()
as the hint means that the new element should be inserted before the
subsequence even if a.begin() is far away. JC van Winkel supplied
precise wording for this proposed resolution, and also for an
alternative resolution in which hints are only used when they are
adjacent to the insertion point.]</i></p>
<p><i>[Copenhagen: the LWG agreed to the original proposed resolution,
in which an insertion hint would be used even when it is far from the
insertion point. This was contingent on seeing a reference
implementation showing that it is possible to implement this
requirement without loss of efficiency. John Potter provided such a
reference implementation.]</i></p>
<p><i>[Redmond: The LWG was reluctant to adopt the proposal that
emerged from Copenhagen: it seemed excessively complicated, and went
beyond fixing the defect that we identified in Toronto. PJP provided
the new wording described in this issue. Nathan agrees that we
shouldn't adopt the more detailed semantics, and notes: "we know that
you can do it efficiently enough with a red-black tree, but there are
other (perhaps better) balanced tree techniques that might differ
enough to make the detailed semantics hard to satisfy."]</i></p>
<p><i>[Curaçao: Nathan should give us the alternative wording he
suggests so the LWG can decide between the two options.]</i></p>
<hr>
<a name="241"><h3>241. Does unique_copy() require CopyConstructible and Assignable?</h3></a><p>
<b>Section:</b> 25.2.8 <a href="lib-algorithms.html#lib.alg.unique"> [lib.alg.unique]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> May 15 2000</p>
<p>Some popular implementations of unique_copy() create temporary
copies of values in the input sequence, at least if the input iterator
is a pointer. Such an implementation is built on the assumption that
the value type is CopyConstructible and Assignable.</p>
<p>It is common practice in the standard that algorithms explicitly
specify any additional requirements that they impose on any of the
types used by the algorithm. An example of an algorithm that creates
temporary copies and correctly specifies the additional requirements
is accumulate(), 26.4.1 <a href="lib-numerics.html#lib.accumulate"> [lib.accumulate]</a>.</p>
<p>Since the specifications of unique() and unique_copy() do not
require CopyConstructible and Assignable of the InputIterator's value
type the above mentioned implementations are not standard-compliant. I
cannot judge whether this is a defect in the standard or a defect in
the implementations.</p>
<p><b>Proposed resolution:</b></p>
<p>In 25.2.8 change:</p>
<blockquote>
-4- Requires: The ranges [first, last) and [result, result+(last-first))
shall not overlap.
</blockquote>
<p>to:</p>
<blockquote>
<p>-4- Requires: The ranges [first, last) and [result,
result+(last-first)) shall not overlap. The expression *result =
*first must be valid. If neither InputIterator nor OutputIterator
meets the requirements of forward iterator then the value type of
InputIterator must be copy constructible. Otherwise copy
constructible is not required. </p>
</blockquote>
<p><i>[Redmond: the original proposed resolution didn't impose an
explicit requirement that the iterator's value type must be copy
constructible, on the grounds that an input iterator's value type must
always be copy constructible. Not everyone in the LWG thought that
this requirement was clear from table 72. It has been suggested that
it might be possible to implement <tt>unique_copy</tt> without
requiring assignability, although current implementations do impose
that requirement. Howard provided new wording.]</i></p>
<p><i>[
Curaçao: The LWG changed the PR editorially to specify
"neither...nor...meet..." as clearer than
"both...and...do not meet...". Change believed to be so
minor as not to require re-review.
]</i></p>
<hr>
<a name="247"><h3>247. <tt>vector</tt>, <tt>deque::insert</tt> complexity</h3></a><p>
<b>Section:</b> 23.2.4.3 <a href="lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 06 June 2000</p>
<p>Paragraph 2 of 23.2.4.3 [lib.vector.modifiers] describes the complexity
of <tt>vector::insert</tt>:</p>
<blockquote>
Complexity: If first and last are forward iterators, bidirectional
iterators, or random access iterators, the complexity is linear in
the number of elements in the range [first, last) plus the distance
to the end of the vector. If they are input iterators, the complexity
is proportional to the number of elements in the range [first, last)
times the distance to the end of the vector.
</blockquote>
<p>First, this fails to address the non-iterator forms of
<tt>insert</tt>.</p>
<p>Second, the complexity for input iterators misses an edge case --
it requires that an arbitrary number of elements can be added at
the end of a <tt>vector</tt> in constant time.</p>
<p>At the risk of strengthening the requirement, I suggest simply</p>
<blockquote>
Complexity: The complexity is linear in the number of elements
inserted plus the distance to the end of the vector.
</blockquote>
<p>For input iterators, one may achieve this complexity by first
inserting at the end of the <tt>vector</tt>, and then using
<tt>rotate</tt>.</p>
<p>I looked to see if <tt>deque</tt> had a similar problem, and was
surprised to find that <tt>deque</tt> places no requirement on the
complexity of inserting multiple elements (23.2.1.3 <a href="lib-containers.html#lib.deque.modifiers"> [lib.deque.modifiers]</a>,
paragraph 3):</p>
<blockquote>
Complexity: In the worst case, inserting a single element into a
deque takes time linear in the minimum of the distance from the
insertion point to the beginning of the deque and the distance
from the insertion point to the end of the deque. Inserting a
single element either at the beginning or end of a deque always
takes constant time and causes a single call to the copy constructor
of T.
</blockquote>
<p>I suggest:</p>
<blockquote>
Complexity: The complexity is linear in the number of elements
inserted plus the shorter of the distances to the beginning and
end of the deque. Inserting a single element at either the
beginning or the end of a deque causes a single call to the copy
constructor of T.
</blockquote>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: It's agreed that there is a defect in complexity of
multi-element insert for vector and deque. For vector, the complexity
should probably be something along the lines of <tt>c<sub>1</sub> * N
+ c<sub>2</sub> * distance(i, end())</tt>. However, there is some
concern about whether it is reasonable to amortize away the copies
that we get from a reallocation whenever we exceed the vector's
capacity. For deque, the situation is somewhat less clear. Deque is
notoriously complicated, and we may not want to impose complexity
requirements that would imply any implementation technique more
complicated than a while loop whose body is a single-element
insert.]</i></p>
<hr>
<a name="253"><h3>253. valarray helper functions are almost entirely useless</h3></a><p>
<b>Section:</b> 26.3.2.1 <a href="lib-numerics.html#lib.valarray.cons"> [lib.valarray.cons]</a>, 26.3.2.2 <a href="lib-numerics.html#lib.valarray.assign"> [lib.valarray.assign]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Robert Klarer <b>Date:</b> 31 Jul 2000</p>
<p>This discussion is adapted from message c++std-lib-7056 posted
November 11, 1999. I don't think that anyone can reasonably claim
that the problem described below is NAD.</p>
<p>These valarray constructors can never be called:</p>
<pre>
template <class T>
valarray<T>::valarray(const slice_array<T> &);
template <class T>
valarray<T>::valarray(const gslice_array<T> &);
template <class T>
valarray<T>::valarray(const mask_array<T> &);
template <class T>
valarray<T>::valarray(const indirect_array<T> &);
</pre>
<p>Similarly, these valarray assignment operators cannot be
called:</p>
<pre>
template <class T>
valarray<T> valarray<T>::operator=(const slice_array<T> &);
template <class T>
valarray<T> valarray<T>::operator=(const gslice_array<T> &);
template <class T>
valarray<T> valarray<T>::operator=(const mask_array<T> &);
template <class T>
valarray<T> valarray<T>::operator=(const indirect_array<T> &);
</pre>
<p>Please consider the following example:</p>
<pre>
#include <valarray>
using namespace std;
int main()
{
valarray<double> va1(12);
valarray<double> va2(va1[slice(1,4,3)]); // line 1
}
</pre>
<p>Since the valarray va1 is non-const, the result of the sub-expression
va1[slice(1,4,3)] at line 1 is an rvalue of type const
std::slice_array<double>. This slice_array rvalue is then used to
construct va2. The constructor that is used to construct va2 is
declared like this:</p>
<pre>
template <class T>
valarray<T>::valarray(const slice_array<T> &);
</pre>
<p>Notice the constructor's const reference parameter. When the
constructor is called, a slice_array must be bound to this reference.
The rules for binding an rvalue to a const reference are in 8.5.3,
paragraph 5 (see also 13.3.3.1.4). Specifically, paragraph 5
indicates that a second slice_array rvalue is constructed (in this
case copy-constructed) from the first one; it is this second rvalue
that is bound to the reference parameter. Paragraph 5 also requires
that the constructor that is used for this purpose be callable,
regardless of whether the second rvalue is elided. The
copy-constructor in this case is not callable, however, because it is
private. Therefore, the compiler should report an error.</p>
<p>Since slice_arrays are always rvalues, the valarray constructor that has a
parameter of type const slice_array<T> & can never be called. The
same reasoning applies to the three other constructors and the four
assignment operators that are listed at the beginning of this post.
Furthermore, since these functions cannot be called, the valarray helper
classes are almost entirely useless.</p>
<p><b>Proposed resolution:</b></p>
<p>slice_array:</p>
<ul>
<li> remove the copy constructor and copy-assignment operator declarations
from the slice_array class template definition in 26.3.5 <a href="lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a> </li>
<li> remove paragraph 3 of 26.3.5 <a href="lib-numerics.html#lib.template.slice.array"> [lib.template.slice.array]</a>
</li>
<li> remove the copy constructor declaration from 26.3.5.1 <a href="lib-numerics.html#lib.cons.slice.arr"> [lib.cons.slice.arr]</a>
</li>
<li> change paragraph 1 of 26.3.5.1 <a href="lib-numerics.html#lib.cons.slice.arr"> [lib.cons.slice.arr]</a> to read "This constructor is declared
to be private. This constructor need not be defined."</li>
<li> remove the copy-assignment operator declaration from 26.3.5.2 <a href="lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a>
</li>
<li> remove the first sentence of paragraph 1 of 26.3.5.2 <a href="lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a>
</li>
<li> Change the first two words of the second sentence of paragraph 1 of
26.3.5.2 <a href="lib-numerics.html#lib.slice.arr.assign"> [lib.slice.arr.assign]</a> to "This function."</li>
</ul>
<p>gslice_array:</p>
<ul>
<li> remove the copy constructor and copy-assignment operator declarations
from the gslice_array class template definition in 26.3.7 <a href="lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a> </li>
<li> remove the note in paragraph 3 of 26.3.7 <a href="lib-numerics.html#lib.template.gslice.array"> [lib.template.gslice.array]</a>
</li>
<li> remove the copy constructor declaration from 26.3.7.1 <a href="lib-numerics.html#lib.gslice.array.cons"> [lib.gslice.array.cons]</a>
</li>
<li> change paragraph 1 of 26.3.7.1 <a href="lib-numerics.html#lib.gslice.array.cons"> [lib.gslice.array.cons]</a> to read "This constructor is declared
to be private. This constructor need not be defined."</li>
<li> remove the copy-assignment operator declaration from 26.3.7.2 <a href="lib-numerics.html#lib.gslice.array.assign"> [lib.gslice.array.assign]</a>
</li>
<li> remove the first sentence of paragraph 1 of 26.3.7.2 <a href="lib-numerics.html#lib.gslice.array.assign"> [lib.gslice.array.assign]</a>
</li>
<li> Change the first two words of the second sentence of paragraph 1 of
26.3.7.2 <a href="lib-numerics.html#lib.gslice.array.assign"> [lib.gslice.array.assign]</a> to "This function."</li>
</ul>
<p>mask_array:</p>
<ul>
<li> remove the copy constructor and copy-assignment operator declarations
from the mask_array class template definition in 26.3.8 <a href="lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a> </li>
<li> remove the note in paragraph 2 of 26.3.8 <a href="lib-numerics.html#lib.template.mask.array"> [lib.template.mask.array]</a>
</li>
<li> remove the copy constructor declaration from 26.3.8.1 <a href="lib-numerics.html#lib.mask.array.cons"> [lib.mask.array.cons]</a>
</li>
<li> change paragraph 1 of 26.3.8.1 <a href="lib-numerics.html#lib.mask.array.cons"> [lib.mask.array.cons]</a> to read "This constructor is declared
to be private. This constructor need not be defined."</li>
<li> remove the first sentence of paragraph 1 of 26.3.8.2 <a href="lib-numerics.html#lib.mask.array.assign"> [lib.mask.array.assign]</a>
</li>
<li> Change the first two words of the second sentence of paragraph 1 of
26.3.8.2 <a href="lib-numerics.html#lib.mask.array.assign"> [lib.mask.array.assign]</a> to "This function."</li>
</ul>
<p>indirect_array:</p>
<ul>
<li>remove the copy constructor and copy-assignment operator declarations
from the indirect_array class definition in 26.3.9 <a href="lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a>
</li>
<li> remove the note in paragraph 2 of 26.3.9 <a href="lib-numerics.html#lib.template.indirect.array"> [lib.template.indirect.array]</a>
</li>
<li> remove the copy constructor declaration from 26.3.9.1 <a href="lib-numerics.html#lib.indirect.array.cons"> [lib.indirect.array.cons]</a>
</li>
<li> change the descriptive text in 26.3.9.1 <a href="lib-numerics.html#lib.indirect.array.cons"> [lib.indirect.array.cons]</a> to read "This constructor is
declared to be private. This constructor need not be defined."</li>
<li> remove the first sentence of paragraph 1 of 26.3.9.2 <a href="lib-numerics.html#lib.indirect.array.assign"> [lib.indirect.array.assign]</a>
</li>
<li> Change the first two words of the second sentence of paragraph 1 of
26.3.9.2 <a href="lib-numerics.html#lib.indirect.array.assign"> [lib.indirect.array.assign]</a> to "This function."</li>
</ul>
<p><i>[This wording is taken from Robert Klarer's reflector message,
c++std-lib-7827. Gabriel Dos Reis agrees that this general solution
is correct.]</i></p>
<p><b>Rationale:</b></p>
<p>Keeping the valarray constructors private is untenable. Merely
making valarray a friend of the helper classes isn't good enough,
because access to the copy constructor is checked in the user's
environment.</p>
<p>Making the assignment operator public is not strictly necessary to
solve this problem. A majority of the LWG <i>(straw poll: 13-4)</i>
believed we should make the assignment operators public, in addition
to the copy constructors, for reasons of symmetry and user
expectation.</p>
<hr>
<a name="254"><h3>254. Exception types in clause 19 are constructed from <tt>std::string</tt>
</h3></a><p>
<b>Section:</b> 19.1 <a href="lib-diagnostics.html#lib.std.exceptions"> [lib.std.exceptions]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 01 Aug 2000</p>
<p>
Many of the standard exception types which implementations are
required to throw are constructed with a const std::string&
parameter. For example:
</p>
<pre>
19.1.5 Class out_of_range [lib.out.of.range]
namespace std {
class out_of_range : public logic_error {
public:
explicit out_of_range(const string& what_arg);
};
}
1 The class out_of_range defines the type of objects thrown as excep-
tions to report an argument value not in its expected range.
out_of_range(const string& what_arg);
Effects:
Constructs an object of class out_of_range.
Postcondition:
strcmp(what(), what_arg.c_str()) == 0.
</pre>
<p>
There are at least two problems with this:
</p>
<ol>
<li>A program which is low on memory may end up throwing
std::bad_alloc instead of out_of_range because memory runs out while
constructing the exception object.</li>
<li>An obvious implementation which stores a std::string data member
may end up invoking terminate() during exception unwinding because the
exception object allocates memory (or rather fails to) as it is being
copied.</li>
</ol>
<p>
There may be no cure for (1) other than changing the interface to
out_of_range, though one could reasonably argue that (1) is not a
defect. Personally I don't care that much if out-of-memory is reported
when I only have 20 bytes left, in the case when out_of_range would
have been reported. People who use exception-specifications might care
a lot, though.
</p>
<p>
There is a cure for (2), but it isn't completely obvious. I think a
note for implementors should be made in the standard. Avoiding
possible termination in this case shouldn't be left up to chance. The
cure is to use a reference-counted "string" implementation
in the exception object. I am not necessarily referring to a
std::string here; any simple reference-counting scheme for a NTBS
would do.
</p>
<p><b>Further discussion, in email:</b></p>
<p>
...I'm not so concerned about (1). After all, a library implementation
can add const char* constructors as an extension, and users don't
<i>need</i> to avail themselves of the standard exceptions, though this is
a lame position to be forced into. FWIW, std::exception and
std::bad_alloc don't require a temporary basic_string.
</p>
<p>
...I don't think the fixed-size buffer is a solution to the problem,
strictly speaking, because you can't satisfy the postcondition
<br>
<tt> strcmp(what(), what_arg.c_str()) == 0</tt>
<br>
For all values of what_arg (i.e. very long values). That means that
the only truly conforming solution requires a dynamic allocation.
</p>
<p><b>Further discussion, from Redmond:</b></p>
<p>The most important progress we made at the Redmond meeting was
realizing that there are two separable issues here: the const
string& constructor, and the copy constructor. If a user writes
something like <tt>throw std::out_of_range("foo")</tt>, the const
string& constructor is invoked before anything gets thrown. The
copy constructor is potentially invoked during stack unwinding.</p>
<p>The copy constructor is a more serious problem, becuase failure
during stack unwinding invokes <tt>terminate</tt>. The copy
constructor must be nothrow. <i>Curaçao: Howard thinks this
requirement is already present.</i>
</p>
<p>The fundamental problem is that it's difficult to get the nothrow
requirement to work well with the requirement that the exception
objects store a string of unbounded size, particularly if you also try
to make the const string& constructor nothrow. Options discussed
include:</p>
<ul>
<li>Limit the size of a string that exception objects are required to
throw: change the postconditions of 19.1.2 <a href="lib-diagnostics.html#lib.domain.error"> [lib.domain.error]</a> paragraph 3
and 19.1.6 <a href="lib-diagnostics.html#lib.runtime.error"> [lib.runtime.error]</a> paragraph 3 to something like this:
"strncmp(what(), what_arg._str(), N) == 0, where N is an
implementation defined constant no smaller than 256".</li>
<li>Allow the const string& constructor to throw, but not the
copy constructor. It's the implementor's responsibility to get it
right. (An implementor might use a simple refcount class.)</li>
<li>Compromise between the two: an implementation is not allowed to
throw if the string's length is less than some N, but, if it doesn't
throw, the string must compare equal to the argument.</li>
<li>Add a new constructor that takes a const char*</li>
</ul>
<p>(Not all of these options are mutually exclusive.)</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: some LWG members thought this was merely a QoI issue,
but most believed that it was at least a borderline defect. There was
more support for nonnormative advice to implementors than for a
normative change.]</i></p>
<p><i>[Redmond: discussed, without definite conclusion. Most LWG
members thought there was a real defect lurking here. A small group
(Herb, Kevlin, Howard, Martin, Dave) will try to make a
recommendation.]</i></p>
<p><i>[Curaçao: Howard will nag the others to work on a recommendation.]</i></p>
<hr>
<a name="258"><h3>258. Missing allocator requirement</h3></a><p>
<b>Section:</b> 20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 22 Aug 2000</p>
<p>
From lib-7752:
</p>
<p>
I've been assuming (and probably everyone else has been assuming) that
allocator instances have a particular property, and I don't think that
property can be deduced from anything in Table 32.
</p>
<p>
I think we have to assume that allocator type conversion is a
homomorphism. That is, if x1 and x2 are of type X, where
X::value_type is T, and if type Y is X::template
rebind<U>::other, then Y(x1) == Y(x2) if and only if x1 == x2.
</p>
<p>
Further discussion: Howard Hinnant writes, in lib-7757:
</p>
<p>
I think I can prove that this is not provable by Table 32. And I agree
it needs to be true except for the "and only if". If x1 != x2, I see no
reason why it can't be true that Y(x1) == Y(x2). Admittedly I can't
think of a practical instance where this would happen, or be valuable.
But I also don't see a need to add that extra restriction. I think we
only need:
</p>
<blockquote>
if (x1 == x2) then Y(x1) == Y(x2)
</blockquote>
<p>
If we decide that == on allocators is transitive, then I think I can
prove the above. But I don't think == is necessarily transitive on
allocators. That is:
</p>
<p>
Given x1 == x2 and x2 == x3, this does not mean x1 == x3.
</p>
<p>Example:</p>
<blockquote>
<p>
x1 can deallocate pointers from: x1, x2, x3 <br>
x2 can deallocate pointers from: x1, x2, x4 <br>
x3 can deallocate pointers from: x1, x3 <br>
x4 can deallocate pointers from: x2, x4
</p>
<p>
x1 == x2, and x2 == x4, but x1 != x4
</p>
</blockquote>
<p><b>Proposed resolution:</b></p>
<p><i>[Toronto: LWG members offered multiple opinions. One
opinion is that it should not be required that <tt>x1 == x2</tt>
implies <tt>Y(x1) == Y(x2)</tt>, and that it should not even be
required that <tt>X(x1) == x1</tt>. Another opinion is that
the second line from the bottom in table 32 already implies the
desired property. This issue should be considered in light of
other issues related to allocator instances.]</i></p>
<hr>
<a name="278"><h3>278. What does iterator validity mean?</h3></a><p>
<b>Section:</b> 23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> P.J. Plauger <b>Date:</b> 27 Nov 2000</p>
<p>
Section 23.2.2.4 [lib.list.ops] states that
</p>
<pre>
void splice(iterator position, list<T, Allocator>& x);
</pre>
<p>
<i>invalidates</i> all iterators and references to list <tt>x</tt>.
</p>
<p>
But what does the C++ Standard mean by "invalidate"? You
can still dereference the iterator to a spliced list element, but
you'd better not use it to delimit a range within the original
list. For the latter operation, it has definitely lost some of its
validity.
</p>
<p>
If we accept the proposed resolution to issue <a href="lwg-defects.html#250">250</a>,
then we'd better clarify that a "valid" iterator need no
longer designate an element within the same container as it once did.
We then have to clarify what we mean by invalidating a past-the-end
iterator, as when a vector or string grows by reallocation. Clearly,
such an iterator has a different kind of validity. Perhaps we should
introduce separate terms for the two kinds of "validity."
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following text to the end of section 24.1 <a href="lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a>,
after paragraph 5:</p>
<blockquote>
An <i>invalid</i> iterator is an iterator that may be
singular. [Footnote: This definition applies to pointers, since
pointers are iterators. The effect of dereferencing an iterator that
has been invalidated is undefined.]
</blockquote>
<p><i>[post-Copenhagen: Matt provided wording.]</i></p>
<p><i>[Redmond: General agreement with the intent, some objections to
the wording. Dave provided new wording.]</i></p>
<p><i>[Curaçao: The definition of "singular" is
contentious. The 278 resolution must be made consistent with
issue <a href="lwg-defects.html#208">208</a> and 24.1/5. Furthermore, a Rationale paragraph
is required.]</i></p>
<hr>
<a name="280"><h3>280. Comparison of reverse_iterator to const reverse_iterator</h3></a><p>
<b>Section:</b> 24.4.1 <a href="lib-iterators.html#lib.reverse.iterators"> [lib.reverse.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Steve Cleary <b>Date:</b> 27 Nov 2000</p>
<p>
This came from an email from Steve Cleary to Fergus in reference to
issue <a href="lwg-active.html#179">179</a>. The library working group briefly discussed
this in Toronto and believed it should be a separate issue. There was
also some reservations about whether this was a worthwhile problem to
fix.
</p>
<p>
Steve said: "Fixing reverse_iterator. std::reverse_iterator can
(and should) be changed to preserve these additional
requirements." He also said in email that it can be done without
breaking user's code: "If you take a look at my suggested
solution, reverse_iterator doesn't have to take two parameters; there
is no danger of breaking existing code, except someone taking the
address of one of the reverse_iterator global operator functions, and
I have to doubt if anyone has ever done that. . . <i>But</i>, just in
case they have, you can leave the old global functions in as well --
they won't interfere with the two-template-argument functions. With
that, I don't see how <i>any</i> user code could break."
</p>
<p><b>Proposed resolution:</b></p>
<p>
<b>Section:</b> 24.4.1.1 <a href="lib-iterators.html#lib.reverse.iterator"> [lib.reverse.iterator]</a>
add/change the following declarations:</p>
<pre>
A) Add a templated assignment operator, after the same manner
as the templated copy constructor, i.e.:
template < class U >
reverse_iterator < Iterator >& operator=(const reverse_iterator< U >& u);
B) Make all global functions (except the operator+) have
two template parameters instead of one, that is, for
operator ==, !=, <, >, <=, >=, - replace:
template < class Iterator >
typename reverse_iterator< Iterator >::difference_type operator-(
const reverse_iterator< Iterator >& x,
const reverse_iterator< Iterator >& y);
with:
template < class Iterator1, class Iterator2 >
typename reverse_iterator < Iterator1 >::difference_type operator-(
const reverse_iterator < Iterator1 > & x,
const reverse_iterator < Iterator2 > & y);
</pre>
<p>
Also make the addition/changes for these signatures in
24.4.1.3 <a href="lib-iterators.html#lib.reverse.iter.ops"> [lib.reverse.iter.ops]</a>.
</p>
<p><i>[
Copenhagen: The LWG is concerned that the proposed resolution
introduces new overloads. Experience shows that introducing
overloads is always risky, and that it would be inappropriate to
make this change without implementation experience. It may be
desirable to provide this feature in a different way.
]</i></p>
<hr>
<a name="282"><h3>282. What types does numpunct grouping refer to?</h3></a><p>
<b>Section:</b> 22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 5 Dec 2000</p>
<p>
Paragraph 16 mistakenly singles out integral types for inserting
thousands_sep() characters. This conflicts with the syntax for floating
point numbers described under 22.2.3.1/2.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change paragraph 16 from:</p>
<blockquote>
For integral types, punct.thousands_sep() characters are inserted into
the sequence as determined by the value returned by punct.do_grouping()
using the method described in 22.2.3.1.2 <a href="lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a>.
</blockquote>
<p>To:</p>
<blockquote>
For arithmetic types, punct.thousands_sep() characters are inserted into
the sequence as determined by the value returned by punct.do_grouping()
using the method described in 22.2.3.1.2 <a href="lib-locales.html#lib.facet.numpunct.virtuals"> [lib.facet.numpunct.virtuals]</a>.
</blockquote>
<p><i>[
Copenhagen: Opinions were divided about whether this is actually an
inconsistency, but at best it seems to have been unintentional. This
is only an issue for floating-point output: The standard is
unambiguous that implementations must parse thousands_sep characters
when performing floating-point. The standard is also unambiguous that
this requirement does not apply to the "C" locale.
]</i></p>
<p><i>[
A survey of existing practice is needed; it is believed that some
implementations do insert thousands_sep characters for floating-point
output and others fail to insert thousands_sep characters for
floating-point input even though this is unambiguously required by the
standard.
]</i></p>
<p><i>[Curaçao: Howard will email Bill and other implementors to try to
move the issue forward.]</i></p>
<hr>
<a name="283"><h3>283. std::replace() requirement incorrect/insufficient</h3></a><p>
<b>Section:</b> 25.2.4 <a href="lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 15 Dec 2000</p>
<p>
The requirements in 25.2.4 <a href="lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a>, p1 that <tt>T</tt> to be
<tt>Assignable</tt> (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>) is not necessary or
sufficient for either of the algorithms. The algorithms require that
<tt>std::iterator_traits<ForwardIterator>::value_type</tt> be
<tt>Assignable</tt> and that both
<tt>std::iterator_traits<ForwardIterator>::value_type</tt> and be
<tt>EqualityComparable</tt> (20.1.1 <a href="lib-utilities.html#lib.equalitycomparable"> [lib.equalitycomparable]</a>) with respect to
one another.
</p>
<p>
<b>Further discussion, from Jeremy</b>:
</p>
<p>There are a number of problems with the requires clauses for the
algorithms in 25.1 <a href="lib-algorithms.html#lib.alg.nonmodifying"> [lib.alg.nonmodifying]</a> and 25.2 <a href="lib-algorithms.html#lib.alg.modifying.operations"> [lib.alg.modifying.operations]</a>. The requires
clause of each algorithm should describe the necessary and sufficient
requirements on the inputs to the algorithm such that the algorithm
compiles and runs properly. Many of the requires clauses fail to do
this. Here is a summary of the kinds of mistakes:</p>
<ol>
<li> Use of EqualityComparable, which only puts requirements on a single
type, when in fact an equality operator is required between two
different types, typically either T and the iterators value_type
or between the value_type's of two different iterators.</li>
<li> Use of Assignable for T when in fact what was needed is Assignable
for the value_type of the iterator, and convertability from T to the
value_type of the iterator. Or for output iterators, the requirement
should be that T is writable to the iterator (output iterators do
not have value types; see issue <a href="lwg-active.html#324">324</a>).</li>
<li> Lack of a requires clause.</li>
</ol>
<p>Here is the list of algorithms that contain mistakes:</p>
<ul>
<li>25.1.2 <a href="lib-algorithms.html#lib.alg.find"> [lib.alg.find]</a>
</li>
<li>25.1.3 <a href="lib-algorithms.html#lib.alg.find.end"> [lib.alg.find.end]</a>
</li>
<li>25.1.4 <a href="lib-algorithms.html#lib.alg.find.first.of"> [lib.alg.find.first.of]</a>
</li>
<li>25.1.6 <a href="lib-algorithms.html#lib.alg.count"> [lib.alg.count]</a>
</li>
<li>25.1.7 <a href="lib-algorithms.html#lib.mismatch"> [lib.mismatch]</a>
</li>
<li>25.1.8 <a href="lib-algorithms.html#lib.alg.equal"> [lib.alg.equal]</a>
</li>
<li>25.1.9 <a href="lib-algorithms.html#lib.alg.search"> [lib.alg.search]</a>
</li>
<li>25.2.4 <a href="lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a>
</li>
<li>25.2.5 <a href="lib-algorithms.html#lib.alg.fill"> [lib.alg.fill]</a>
</li>
<li>25.2.7 <a href="lib-algorithms.html#lib.alg.remove"> [lib.alg.remove]</a>
</li>
</ul>
<p>Also, in the requirements for EqualityComparable, the requirement that
the operator be defined for const objects is lacking.</p>
<p><b>Proposed resolution:</b></p>
<p>20.1.1 <a href="lib-utilities.html#lib.equalitycomparable"> [lib.equalitycomparable]</a> Change p1 from</p>
<blockquote>
In Table 28, T is a type to be supplied by a C++ program instantiating
a template, a, b, and c are values of type T.
</blockquote>
<p>to</p>
<blockquote>
In Table 28, T is a type to be supplied by a C++ program instantiating
a template, a, b, and c are values of type const T.
</blockquote>
<p>25.1.2 <a href="lib-algorithms.html#lib.alg.find"> [lib.alg.find]</a> Change p1 from</p>
<blockquote>
Requires: Type T is EqualityComparable (20.1.1).
</blockquote>
<p>to </p>
<blockquote>
Requires: There must be a equality operator defined that accepts type
std::iterator_traits<InputIterator>::reference for the left operand
and const T for the right operand.
</blockquote>
<p>25.1.3 <a href="lib-algorithms.html#lib.alg.find.end"> [lib.alg.find.end]</a> Add the following requires clause</p>
<blockquote>
Requires: There must be an equality operator defined that accepts
type const std::iterator_traits<ForwardIterator1>::value_type for the
left operand and const
std::iterator_traits<ForwardIterator2>::value_type for the right
operand.
</blockquote>
<p>25.1.4 <a href="lib-algorithms.html#lib.alg.find.first.of"> [lib.alg.find.first.of]</a> Add the following requires clause</p>
<blockquote>
Requires: There must be an equality operator defined that accepts
type const std::iterator_traits<ForwardIterator1>::value_type for the
left operand and const
std::iterator_traits<ForwardIterator2>::value_type for the right
operand.
</blockquote>
<p>25.1.5 <a href="lib-algorithms.html#lib.alg.adjacent.find"> [lib.alg.adjacent.find]</a> Add the following requires clause</p>
<blockquote>
Requires: T must be EqualityComparable (20.1.1).
</blockquote>
<p>25.1.6 <a href="lib-algorithms.html#lib.alg.count"> [lib.alg.count]</a> Change p1 from</p>
<blockquote>
Requires: Type T is EqualityComparable (20.1.1).
</blockquote>
<p>to</p>
<blockquote>
Requires: There must be a equality operator defined that accepts type
std::iterator_traits<InputIterator>::reference for the left operand
and const T for the right operand.
</blockquote>
<p>25.1.7 <a href="lib-algorithms.html#lib.mismatch"> [lib.mismatch]</a> Add the following requires clause</p>
<blockquote>
Requires: There must be an equality operator defined that accepts type
std::iterator_traits<InputIterator1>::reference for the left operand
and std::iterator_traits<InputIterator2>::reference for the right operand.
</blockquote>
<p>25.1.8 <a href="lib-algorithms.html#lib.alg.equal"> [lib.alg.equal]</a> Add the following requires clause</p>
<blockquote>
Requires: There must be an equality operator defined that accepts type
std::iterator_traits<InputIterator1>::reference for the left operand
and std::iterator_traits<InputIterator2>::reference for the right operand.
</blockquote>
<p>25.1.9 <a href="lib-algorithms.html#lib.alg.search"> [lib.alg.search]</a> Add the following requires clause</p>
<blockquote>
Requires: There must be an equality operator defined that accepts
type const std::iterator_traits<ForwardIterator1>::value_type for
the left operand and const
std::iterator_traits<ForwardIterator2>::value_type for the right
operand.
</blockquote>
<p>Change change p4 from</p>
<blockquote>
Requires: Type T is EqualityComparable (20.1.1), type Size is
convertible to integral type (4.7.12.3).
</blockquote>
<p>to</p>
<blockquote>
Requires: There must be an equality operator defined that accepts
const std::iterator_traits<ForwardIterator>::value_type for the left
operand and const T for the right operand. The type Size is convertible to
integral type (4.7.12.3).
</blockquote>
<p>25.2.4 <a href="lib-algorithms.html#lib.alg.replace"> [lib.alg.replace]</a> Change p1 from</p>
<blockquote>
Requires: Type T is Assignable (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>) (and, for replace(),
EqualityComparable (20.1.1 <a href="lib-utilities.html#lib.equalitycomparable"> [lib.equalitycomparable]</a>)).
</blockquote>
<p>to</p>
<blockquote>
Requires: Type std::iterator_traits<ForwardIterator>::value_type
is Assignable (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>) and the type const T is convertible to
std::iterator_traits<ForwardIterator>::value_type. For replace(), an
equality operator must be defined that accepts type
std::iterator_traits<ForwardIterator>::reference for the left operand
and const T for the right operand.
</blockquote>
<p>and change p4 from</p>
<blockquote>
Requires: Type T is Assignable (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>) (and, for replace_copy(),
EqualityComparable (20.1.1 <a href="lib-utilities.html#lib.equalitycomparable"> [lib.equalitycomparable]</a>)). The ranges [first, last) and [result,
result + (last - first)) shall not overlap.
</blockquote>
<p>to</p>
<blockquote>
Requires: Both types const T and
std::iterator_traits<InputIterator>::reference are writable to the
OutputIterator type. For replace_copy() an equality operator must be
defined that accepts type
std::iterator_traits<InputIterator>::reference for the left operand
and const T for the right operand. The ranges [first, last) and [result,
result + (last - first)) shall not overlap.
</blockquote>
<p>25.2.5 <a href="lib-algorithms.html#lib.alg.fill"> [lib.alg.fill]</a> Change p1 from</p>
<blockquote>
Requires: Type T is Assignable (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> ). Size is convertible to an integral
type (3.9.1 <a href="basic.html#basic.fundamental"> [basic.fundamental]</a> ).
</blockquote>
<p>to</p>
<blockquote>
Requires: Type const T is writable to the OutputIterator. Size is
convertible to an integral type (3.9.1 <a href="basic.html#basic.fundamental"> [basic.fundamental]</a> ).
</blockquote>
<p>25.2.7 <a href="lib-algorithms.html#lib.alg.remove"> [lib.alg.remove]</a> Change p1 from</p>
<blockquote>
Requires: Type T is EqualityComparable (20.1.1 <a href="lib-utilities.html#lib.equalitycomparable"> [lib.equalitycomparable]</a>).
</blockquote>
<p>to</p>
<blockquote>
Requires: There must be an equality operator defined that accepts
type const std::iterator_traits<ForwardIterator>::value_type for the left
operand and const T for the right operand. The type
std::iterator_traits<ForwardIterator>::value_type must be Assignable
(23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a>).
</blockquote>
<p><i>[Curaçao: Jeremy reports he has run the changes through his
automated test tools. At the request of the LWG, Jeremy will reword
the PR in terms of valid expressions rather than "equality
operator".]</i></p>
<hr>
<a name="290"><h3>290. Requirements to for_each and its function object</h3></a><p>
<b>Section:</b> 25.1.1 <a href="lib-algorithms.html#lib.alg.foreach"> [lib.alg.foreach]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Angelika Langer <b>Date:</b> 03 Jan 2001</p>
<p>The specification of the for_each algorithm does not have a
"Requires" section, which means that there are no
restrictions imposed on the function object whatsoever. In essence it
means that I can provide any function object with arbitrary side
effects and I can still expect a predictable result. In particular I
can expect that the function object is applied exactly last - first
times, which is promised in the "Complexity" section.
</p>
<p>I don't see how any implementation can give such a guarantee
without imposing requirements on the function object.
</p>
<p>Just as an example: consider a function object that removes
elements from the input sequence. In that case, what does the
complexity guarantee (applies f exactly last - first times) mean?
</p>
<p>One can argue that this is obviously a nonsensical application and
a theoretical case, which unfortunately it isn't. I have seen
programmers shooting themselves in the foot this way, and they did not
understand that there are restrictions even if the description of the
algorithm does not say so.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add a "Requires" section to section 25.1.1 similar to those
proposed for transform and the numeric algorithms (see issue
<a href="lwg-defects.html#242">242</a>):
</p>
<blockquote>
-2- <b>Requires</b>: In the range [first, last], f shall not invalidate
iterators or subranges.
</blockquote>
<p><i>[Copenhagen: The LWG agrees that a function object passed to an
algorithm should not invalidate iterators in the range that the
algorithm is operating on. The LWG believes that this should be a
blanket statement in Clause 25, not just a special requirement for
<tt>for_each</tt>.
]</i></p>
<hr>
<a name="291"><h3>291. Underspecification of set algorithms</h3></a><p>
<b>Section:</b> 25.3.5 <a href="lib-algorithms.html#lib.alg.set.operations"> [lib.alg.set.operations]</a> <b>Status:</b> <a href="lwg-active.html#Review">Review</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 03 Jan 2001</p>
<p>
The standard library contains four algorithms that compute set
operations on sorted ranges: <tt>set_union</tt>, <tt>set_intersection</tt>,
<tt>set_difference</tt>, and <tt>set_symmetric_difference</tt>. Each
of these algorithms takes two sorted ranges as inputs, and writes the
output of the appropriate set operation to an output range. The elements
in the output range are sorted.
</p>
<p>
The ordinary mathematical definitions are generalized so that they
apply to ranges containing multiple copies of a given element. Two
elements are considered to be "the same" if, according to an
ordering relation provided by the user, neither one is less than the
other. So, for example, if one input range contains five copies of an
element and another contains three, the output range of <tt>set_union</tt>
will contain five copies, the output range of
<tt>set_intersection</tt> will contain three, the output range of
<tt>set_difference</tt> will contain two, and the output range of
<tt>set_symmetric_difference</tt> will contain two.
</p>
<p>
Because two elements can be "the same" for the purposes
of these set algorithms, without being identical in other respects
(consider, for example, strings under case-insensitive comparison),
this raises a number of unanswered questions:
</p>
<ul>
<li>If we're copying an element that's present in both of the
input ranges, which one do we copy it from?</li>
<li>If there are <i>n</i> copies of an element in the relevant
input range, and the output range will contain fewer copies (say
<i>m</i>) which ones do we choose? The first <i>m</i>, or the last
<i>m</i>, or something else?</li>
<li>Are these operations stable? That is, does a run of equivalent
elements appear in the output range in the same order as as it
appeared in the input range(s)?</li>
</ul>
<p>
The standard should either answer these questions, or explicitly
say that the answers are unspecified. I prefer the former option,
since, as far as I know, all existing implementations behave the
same way.
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following to the end of 25.3.5.2 <a href="lib-algorithms.html#lib.set.union"> [lib.set.union]</a> paragraph 5:</p>
<blockquote>
If [first1, last1) contains <i>m</i> elements that are equivalent to
each other and [first2, last2) contains <i>n</i> elements that are
equivalent to them, then max(<i>m</i>, <i>n</i>) of these elements
will be copied to the output range: all <i>m</i> of these elements
from [first1, last1), and the last max(<i>n-m</i>, 0) of them from
[first2, last2), in that order.
</blockquote>
<p>Add the following to the end of 25.3.5.3 <a href="lib-algorithms.html#lib.set.intersection"> [lib.set.intersection]</a> paragraph 5:</p>
<blockquote>
If [first1, last1) contains <i>m</i> elements that are equivalent to each
other and [first2, last2) contains <i>n</i> elements that are
equivalent to them, the first min(<i>m</i>, <i>n</i>) of those
elements from [first1, last1) are copied to the output range.
</blockquote>
<p>Add a new paragraph, <b>Notes</b>, after 25.3.5.4 <a href="lib-algorithms.html#lib.set.difference"> [lib.set.difference]</a>
paragraph 4:</p>
<blockquote>
If [first1, last1) contains <i>m</i> elements that are equivalent to each
other and [first2, last2) contains <i>n</i> elements that are
equivalent to them, the last max(<i>m-n</i>, 0) elements from
[first1, last1) are copied to the output range.
</blockquote>
<p>Add a new paragraph, <b>Notes</b>, after 25.3.5.5 <a href="lib-algorithms.html#lib.set.symmetric.difference"> [lib.set.symmetric.difference]</a>
paragraph 4:</p>
<blockquote>
If [first1, last1) contains <i>m</i> elements that are equivalent to
each other and [first2, last2) contains <i>n</i> elements that are
equivalent to them, then |<i>m - n</i>| of those elements will be
copied to the output range: the last <i>m - n</i> of these elements
from [first1, last1) if <i>m</i> > <i>n</i>, and the last <i>n -
m</i> of these elements from [first2, last2) if <i>m</i> < <i>n</i>.
</blockquote>
<p><i>[Curaçao: Missing Rationale and missing status comments from
Redmond made discussion difficult. For union, doesn't the standard
already say this? Howard, others think maybe so. Several thought the
PR may be "too complicated".]</i></p>
<hr>
<a name="294"><h3>294. User defined macros and standard headers</h3></a><p>
<b>Section:</b> 17.4.3.1.1 <a href="lib-intro.html#lib.macro.names"> [lib.macro.names]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> James Kanze <b>Date:</b> 11 Jan 2001</p>
<p>Paragraph 2 of 17.4.3.1.1 <a href="lib-intro.html#lib.macro.names"> [lib.macro.names]</a> reads: "A
translation unit that includes a header shall not contain any macros
that define names declared in that header." As I read this, it
would mean that the following program is legal:</p>
<pre>
#define npos 3.14
#include <sstream>
</pre>
<p>since npos is not defined in <sstream>. It is, however, defined
in <string>, and it is hard to imagine an implementation in
which <sstream> didn't include <string>.</p>
<p>I think that this phrase was probably formulated before it was
decided that a standard header may freely include other standard
headers. The phrase would be perfectly appropriate for C, for
example. In light of 17.4.4.1 <a href="lib-intro.html#lib.res.on.headers"> [lib.res.on.headers]</a> paragraph 1, however,
it isn't stringent enough.</p>
<p><b>Proposed resolution:</b></p>
<p>In paragraph 2 of 17.4.3.1.1 <a href="lib-intro.html#lib.macro.names"> [lib.macro.names]</a>, change "A
translation unit that includes a header shall not contain any macros
that define names declared in that header." to "A
translation unit that includes a header shall not contain any macros
that define names declared in any standard header."</p>
<p><i>[Copenhagen: the general idea is clearly correct, but there is
concern about making sure that the two paragraphs in 17.4.3.1.1 <a href="lib-intro.html#lib.macro.names"> [lib.macro.names]</a> remain consistent. Nathan will provide new
wording.]</i></p>
<hr>
<a name="299"><h3>299. Incorrect return types for iterator dereference</h3></a><p>
<b>Section:</b> 24.1.4 <a href="lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>, 24.1.5 <a href="lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> John Potter <b>Date:</b> 22 Jan 2001</p>
<p>
In section 24.1.4 <a href="lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>,
Table 75 gives the return type of *r-- as convertible to T. This is
not consistent with Table 74 which gives the return type of *r++ as
T&. *r++ = t is valid while *r-- = t is invalid.
</p>
<p>
In section 24.1.5 <a href="lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a>,
Table 76 gives the return type of a[n] as convertible to T. This is
not consistent with the semantics of *(a + n) which returns T& by
Table 74. *(a + n) = t is valid while a[n] = t is invalid.
</p>
<p>
Discussion from the Copenhagen meeting: the first part is
uncontroversial. The second part, operator[] for Random Access
Iterators, requires more thought. There are reasonable arguments on
both sides. Return by value from operator[] enables some potentially
useful iterators, e.g. a random access "iota iterator" (a.k.a
"counting iterator" or "int iterator"). There isn't any obvious way
to do this with return-by-reference, since the reference would be to a
temporary. On the other hand, <tt>reverse_iterator</tt> takes an
arbitrary Random Access Iterator as template argument, and its
operator[] returns by reference. If we decided that the return type
in Table 76 was correct, we would have to change
<tt>reverse_iterator</tt>. This change would probably affect user
code.
</p>
<p>
History: the contradiction between <tt>reverse_iterator</tt> and the
Random Access Iterator requirements has been present from an early
stage. In both the STL proposal adopted by the committee
(N0527==94-0140) and the STL technical report (HPL-95-11 (R.1), by
Stepanov and Lee), the Random Access Iterator requirements say that
operator[]'s return value is "convertible to T". In N0527
reverse_iterator's operator[] returns by value, but in HPL-95-11
(R.1), and in the STL implementation that HP released to the public,
reverse_iterator's operator[] returns by reference. In 1995, the
standard was amended to reflect the contents of HPL-95-11 (R.1). The
original intent for operator[] is unclear.
</p>
<p>
In the long term it may be desirable to add more fine-grained
iterator requirements, so that access method and traversal strategy
can be decoupled. (See "Improved Iterator Categories and
Requirements", N1297 = 01-0011, by Jeremy Siek.) Any decisions
about issue 299 should keep this possibility in mind.
</p>
<p><b>Proposed resolution:</b></p>
<p>In section 24.1.4 <a href="lib-iterators.html#lib.bidirectional.iterators"> [lib.bidirectional.iterators]</a>, change the return type in table
75 from "convertible to T" to T&.</p>
<p>In section 24.1.5 <a href="lib-iterators.html#lib.random.access.iterators"> [lib.random.access.iterators]</a>, change the return type in table
76 from "convertible to T" to T&.</p>
<p><i>[Curaçao: Jeremy volunteered to work on this issue.]</i></p>
<hr>
<a name="300"><h3>300. list::merge() specification incomplete</h3></a><p>
<b>Section:</b> 23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> John Pedretti <b>Date:</b> 23 Jan 2001</p>
<p>
The "Effects" clause for list::merge() (23.2.2.4, p23)
appears to be incomplete: it doesn't cover the case where the argument
list is identical to *this (i.e., this == &x). The requirement in the
note in p24 (below) is that x be empty after the merge which is surely
unintended in this case.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change 23.2.2.4, p23 to:
</p>
<blockquote>
<b>Effects</b>: If &x == this, does nothing; otherwise, merges the
argument list into the list.
</blockquote>
<p><i>[Copenhagen: The proposed resolution does not fix all of the
problems in 23.2.2.4 <a href="lib-containers.html#lib.list.ops"> [lib.list.ops]</a>, p22-25. Three different
paragraphs (23, 24, 25) describe the effects of <tt>merge</tt>.
Changing p23, without changing the other two, appears to introduce
contradictions. Additionally, "merges the argument list into the
list" is excessively vague.]</i></p>
<p><i>[Curaçao: Robert Klarer volunteers to work on this issue.]</i></p>
<hr>
<a name="304"><h3>304. Must <tt>*a</tt> return an lvalue when <tt>a</tt> is an input iterator?</h3></a><p>
<b>Section:</b> 24.1 <a href="lib-iterators.html#lib.iterator.requirements"> [lib.iterator.requirements]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 5 Feb 2001</p>
<p>
We all "know" that input iterators are allowed to produce
values when dereferenced of which there is no other in-memory copy.
</p>
<p>
But: Table 72, with a careful reading, seems to imply that this can only be
the case if the value_type has no members (e.g. is a built-in type).
</p>
<p>The problem occurs in the following entry:</p>
<pre>
a->m pre: (*a).m is well-defined
Equivalent to (*a).m
</pre>
<p>
<tt>*a.m</tt> can be well-defined if <tt>*a</tt> is not a reference
type, but since <tt>operator->()</tt> must return a pointer for
<tt>a->m</tt> to be well-formed, it needs something to return a
pointer <i>to</i>. This seems to indicate that <tt>*a</tt> must be
buffered somewhere to make a legal input iterator.
</p>
<p>I don't think this was intentional.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Copenhagen: the two obvious possibilities are to keep the
<tt>operator-></tt> requirement for Input Iterators, and put
in a non-normative note describing how it can be implemented with
proxies, or else moving the <tt>operator-></tt> requirement
from Input Iterator to Forward Iterator. If we do the former
we'll also have to change <tt>istreambuf_iterator</tt>, because
it has no <tt>operator-></tt>. A straw poll showed roughly equal
support for the two options.]</i></p>
<hr>
<a name="305"><h3>305. Default behavior of codecvt<wchar_t, char, mbstate_t>::length()</h3></a><p>
<b>Section:</b> 22.2.1.5.2 <a href="lib-locales.html#lib.locale.codecvt.virtuals"> [lib.locale.codecvt.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 24 Jan 2001</p>
<p>22.2.1.5/3 introduces codecvt in part with:</p>
<blockquote>
codecvt<wchar_t,char,mbstate_t> converts between the native
character sets for tiny and wide characters. Instantiations on
mbstate_t perform conversion between encodings known to the library
implementor.
</blockquote>
<p>But 22.2.1.5.2/10 describes do_length in part with:</p>
<blockquote>
... codecvt<wchar_t, char, mbstate_t> ... return(s) the lesser of max and
(from_end-from).
</blockquote>
<p>
The semantics of do_in and do_length are linked. What one does must
be consistent with what the other does. 22.2.1.5/3 leads me to
believe that the vendor is allowed to choose the algorithm that
codecvt<wchar_t,char,mbstate_t>::do_in performs so that it makes
his customers happy on a given platform. But 22.2.1.5.2/10 explicitly
says what codecvt<wchar_t,char,mbstate_t>::do_length must
return. And thus indirectly specifies the algorithm that
codecvt<wchar_t,char,mbstate_t>::do_in must perform. I believe
that this is not what was intended and is a defect.
</p>
<p>Discussion from the -lib reflector:
<br>This proposal would have the effect of making the semantics of
all of the virtual functions in <tt>codecvt<wchar_t, char,
mbstate_t></tt> implementation specified. Is that what we want, or
do we want to mandate specific behavior for the base class virtuals
and leave the implementation specified behavior for the codecvt_byname
derived class? The tradeoff is that former allows implementors to
write a base class that actually does something useful, while the
latter gives users a way to get known and specified---albeit
useless---behavior, and is consistent with the way the standard
handles other facets. It is not clear what the original intention
was.</p>
<p>
Nathan has suggest a compromise: a character that is a widened version
of the characters in the basic execution character set must be
converted to a one-byte sequence, but there is no such requirement
for characters that are not part of the basic execution character set.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change 22.2.1.5.2/5 from:
</p>
<p>
The instantiations required in Table 51 (lib.locale.category), namely
codecvt<wchar_t,char,mbstate_t> and
codecvt<char,char,mbstate_t>, store no characters. Stores no more
than (to_limit-to) destination elements. It always leaves the to_next
pointer pointing one beyond the last element successfully stored.
</p>
<p>
to:
</p>
<p>
Stores no more than (to_limit-to) destination elements, and leaves the
to_next pointer pointing one beyond the last element successfully
stored. codecvt<char,char,mbstate_t> stores no characters.
</p>
<p>Change 22.2.1.5.2/10 from:</p>
<blockquote>
-10- Returns: (from_next-from) where from_next is the largest value in
the range [from,from_end] such that the sequence of values in the
range [from,from_next) represents max or fewer valid complete
characters of type internT. The instantiations required in Table 51
(21.1.1.1.1), namely codecvt<wchar_t, char, mbstate_t> and
codecvt<char, char, mbstate_t>, return the lesser of max and
(from_end-from).
</blockquote>
<p>to:</p>
<blockquote>
-10- Returns: (from_next-from) where from_next is the largest value in
the range [from,from_end] such that the sequence of values in the range
[from,from_next) represents max or fewer valid complete characters of
type internT. The instantiation codecvt<char, char, mbstate_t> returns
the lesser of max and (from_end-from).
</blockquote>
<p><i>[Redmond: Nathan suggested an alternative resolution: same as
above, but require that, in the default encoding, a character from the
basic execution character set would map to a single external
character. The straw poll was 8-1 in favor of the proposed
resolution.]</i></p>
<p><b>Rationale:</b></p>
<p>The default encoding should be whatever users of a given platform
would expect to be the most natural. This varies from platform to
platform. In many cases there is a preexisting C library, and users
would expect the default encoding to be whatever C uses in the default
"C" locale. We could impose a guarantee like the one Nathan suggested
(a character from the basic execution character set must map to a
single external character), but this would rule out important
encodings that are in common use: it would rule out JIS, for
example, and it would rule out a fixed-width encoding of UCS-4.</p>
<p><i>[Curaçao: fixed rationale typo at the request of Ichiro Koshida;
"shift-JIS" changed to "JIS".]</i></p>
<hr>
<a name="309"><h3>309. Does sentry catch exceptions?</h3></a><p>
<b>Section:</b> 27.6 <a href="lib-iostreams.html#lib.iostream.format"> [lib.iostream.format]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 19 Mar 2001</p>
<p>
The descriptions of the constructors of basic_istream<>::sentry
(27.6.1.1.2 <a href="lib-iostreams.html#lib.istream::sentry"> [lib.istream::sentry]</a>) and basic_ostream<>::sentry
(27.6.2.3 <a href="lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a>) do not explain what the functions do in
case an exception is thrown while they execute. Some current
implementations allow all exceptions to propagate, others catch them
and set ios_base::badbit instead, still others catch some but let
others propagate.
</p>
<p>
The text also mentions that the functions may call setstate(failbit)
(without actually saying on what object, but presumably the stream
argument is meant). That may have been fine for
basic_istream<>::sentry prior to issue <a href="lwg-defects.html#195">195</a>, since
the function performs an input operation which may fail. However,
issue <a href="lwg-defects.html#195">195</a> amends 27.6.1.1.2 <a href="lib-iostreams.html#lib.istream::sentry"> [lib.istream::sentry]</a>, p2 to
clarify that the function should actually call setstate(failbit |
eofbit), so the sentence in p3 is redundant or even somewhat
contradictory.
</p>
<p>
The same sentence that appears in 27.6.2.3 <a href="lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a>, p3
doesn't seem to be very meaningful for basic_istream<>::sentry
which performs no input. It is actually rather misleading since it
would appear to guide library implementers to calling
setstate(failbit) when os.tie()->flush(), the only called function,
throws an exception (typically, it's badbit that's set in response to
such an event).
</p>
<p><b>Proposed resolution:</b></p>
<p>Add the following paragraph immediately after
27.6.1.1.2 <a href="lib-iostreams.html#lib.istream::sentry"> [lib.istream::sentry]</a>, p5</p>
<blockquote>
<p>
If an exception is thrown during the preparation then ios::badbit
is turned on* in is's error state.
</p>
<p>
[Footnote: This is done without causing an ios::failure to be thrown.
--- end footnote]
</p>
<p>
If (is.exceptions() & ios_base::badbit)!= 0 then the exception is
rethrown.
</p>
</blockquote>
<p>And strike the following sentence from 27.6.1.1.2 <a href="lib-iostreams.html#lib.istream::sentry"> [lib.istream::sentry]</a>, p5</p>
<blockquote>
During preparation, the constructor may call setstate(failbit)
(which may throw ios_base::failure (lib.iostate.flags))
</blockquote>
<p>Add the following paragraph immediately after
27.6.2.3 <a href="lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a>, p3</p>
<blockquote>
<p>
If an exception is thrown during the preparation then ios::badbit
is turned on* in os's error state.
</p>
<p>
[Footnote: This is done without causing an ios::failure to be
thrown. --- end footnote]
</p>
<p>
If (os.exceptions() & ios_base::badbit)!= 0 then the exception
is rethrown.
</p>
</blockquote>
<p>And strike the following sentence from 27.6.2.3 <a href="lib-iostreams.html#lib.ostream::sentry"> [lib.ostream::sentry]</a>, p3</p>
<blockquote>
During preparation, the constructor may call setstate(failbit)
(which may throw ios_base::failure (lib.iostate.flags))
</blockquote>
<p>(Note that the removal of the two sentences means that the ctors
will not be able to report the failure of any implementation-dependent
operations referred to in footnotes 280 and 293, unless such
operations throw an exception.)</p>
<p><i>[
Copenhagen: It was agreed that there was an issue here, but there was
disagreement about the resolution. Some LWG members argued that a
sentry's constructor should not catch exceptions, because sentries
should only be used within (un)formatted input functions and that
exception handling is the responsibility of those functions, not of
the sentries.
]</i></p>
<hr>
<a name="320"><h3>320. list::assign overspecified</h3></a><p>
<b>Section:</b> 23.2.2.1 <a href="lib-containers.html#lib.list.cons"> [lib.list.cons]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 17 May 2001</p>
<p>
Section 23.2.2.1, paragraphs 6-8 specify that list assign (both forms) have
the "effects" of a call to erase followed by a call to insert.
</p>
<p>
I would like to document that implementers have the freedom to implement
assign by other methods, as long as the end result is the same and the
exception guarantee is as good or better than the basic guarantee.
</p>
<p>
The motivation for this is to use T's assignment operator to recycle
existing nodes in the list instead of erasing them and reallocating
them with new values. It is also worth noting that, with careful
coding, most common cases of assign (everything but assignment with
true input iterators) can elevate the exception safety to strong if
T's assignment has a nothrow guarantee (with no extra memory cost).
Metrowerks does this. However I do not propose that this subtlety be
standardized. It is a QoI issue. </p>
<p>Existing practise:
Metrowerks and SGI recycle nodes, Dinkumware and Rogue Wave don't.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change 23.2.2.1/7 from:</p>
<blockquote>
<p>Effects:</p>
<pre>
erase(begin(), end());
insert(begin(), first, last);
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Replaces the contents of the list with the range [first, last).</p>
</blockquote>
<p>In 23.1.1 <a href="lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a>, in Table 67 (sequence requirements),
add two new rows:</p>
<pre>
a.assign(i,j) void pre: i,j are not iterators into a.
Replaces elements in a with a copy
of [i, j).
a.assign(n,t) void pre: t is not a reference into a.
Replaces elements in a with n copies
of t.
</pre>
<p>Change 23.2.2.1/8 from:</p>
<blockquote>
<p>Effects:</p>
<pre>
erase(begin(), end());
insert(begin(), n, t);
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<p>Effects: Replaces the contents of the list with n copies of t.</p>
</blockquote>
<p><i>[Redmond: Proposed resolution was changed slightly. Previous
version made explicit statement about exception safety, which wasn't
consistent with the way exception safety is expressed elsewhere.
Also, the change in the sequence requirements is new. Without that
change, the proposed resolution would have required that assignment of
a subrange would have to work. That too would have been
overspecification; it would effectively mandate that assignment use a
temporary. Howard provided wording.
]</i></p>
<p><i>[Curaçao: Made editorial improvement in wording; changed
"Replaces elements in a with copies of elements in [i, j)."
with "Replaces the elements of a with a copy of [i, j)."
Changes not deemed serious enough to requre rereview.]</i></p>
<hr>
<a name="323"><h3>323. abs() overloads in different headers</h3></a><p>
<b>Section:</b> 26.5 <a href="lib-numerics.html#lib.c.math"> [lib.c.math]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 4 June 2001</p>
<p>Currently the standard mandates the following overloads of
abs():</p>
<pre>
abs(long), abs(int) in <cstdlib>
abs(float), abs(double), abs(long double) in <cmath>
template<class T> T abs(const complex<T>&) in <complex>
template<class T> valarray<T> abs(const valarray<T>&); in <valarray>
</pre>
<p>
The problem is that having only some overloads visible of a function
that works on "implicitly inter-convertible" types is dangerous in
practice. The headers that get included at any point in a translation
unit can change unpredictably during program
development/maintenance. The wrong overload might be unintentionally
selected.
</p>
<p>
Currently, there is nothing that mandates the simultaneous visibility
of these overloads. Indeed, some vendors have begun fastidiously
reducing dependencies among their (public) headers as a QOI issue: it
helps people to write portable code by refusing to compile unless all
the correct headers are #included.
</p>
<p>The same issue may exist for other functions in the library.</p>
<p>Redmond: PJP reports that C99 adds two new kinds of abs: comples,
and int_max_abs.</p>
<p>Related issue: <a href="lwg-closed.html#343">343</a>.</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Redmond: General agreement that the current situation is
somewhat fragile. No consensus on whether it's more fragile than any
number of other things, or whether there's any good way to fix it.
Walter suggests that <tt>abs</tt> should be defined for all built-in
types in both <cmath> and <cstdlib>, but that no effort
should be made to put all overloads for class types in one place.
Beman suggests closing this issue as "NAD Future", and adding a
<all> header as an extension. The <all> header would
solve a more general problem: users who can't remember which names are
defined in which headers. (See issue <a href="lwg-closed.html#343">343</a>)]</i></p>
<hr>
<a name="324"><h3>324. Do output iterators have value types?</h3></a><p>
<b>Section:</b> 24.1.2 <a href="lib-iterators.html#lib.output.iterators"> [lib.output.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Dave Abrahams <b>Date:</b> 7 June 2001</p>
<p>Table 73 suggests that output iterators have value types. It
requires the expression "*a = t". Additionally, although Table 73
never lists "a = t" or "X(a) = t" in the "expressions" column, it
contains a note saying that "a = t" and "X(a) = t" have equivalent
(but nowhere specified!) semantics.</p>
<p>According to 24.1/9, t is supposed to be "a value of value type
T":</p>
<blockquote>
In the following sections, a and b denote values of X, n denotes a
value of the difference type Distance, u, tmp, and m denote
identifiers, r denotes a value of X&, t denotes a value of
value type T.
</blockquote>
<p>Two other parts of the standard that are relevant to whether
output iterators have value types:</p>
<ul>
<li>24.1/1 says "All iterators i support the expression *i,
resulting in a value of some class, enumeration, or built-in type
T, called the value type of the iterator".</li>
<li>
24.3.1/1, which says "In the case of an output iterator, the types
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type are both defined as void."
</li>
</ul>
<p>The first of these passages suggests that "*i" is supposed to
return a useful value, which contradicts the note in 24.1.2/2 saying
that the only valid use of "*i" for output iterators is in an
expression of the form "*i = t". The second of these passages appears
to contradict Table 73, because it suggests that "*i"'s return value
should be void. The second passage is also broken in the case of a an
iterator type, like non-const pointers, that satisfies both the output
iterator requirements and the forward iterator requirements.</p>
<p>What should the standard say about <tt>*i</tt>'s return value when
i is an output iterator, and what should it say about that t is in the
expression "*i = t"? Finally, should the standard say anything about
output iterators' pointer and reference types?</p>
<p><b>Proposed resolution:</b></p>
<p>24.1 p1, change</p>
<blockquote>
<p>All iterators <tt>i</tt> support the expression <tt>*i</tt>, resulting
in a value of some class, enumeration, or built-in type <tt>T</tt>,
called the value type of the iterator.</p>
</blockquote>
<p>to</p>
<blockquote>
<p>All input iterators <tt>i</tt> support the expression <tt>*i</tt>,
resulting in a value of some class, enumeration, or built-in type
<tt>T</tt>, called the value type of the iterator. All output
iterators support the expression <tt>*i = o</tt> where <tt>o</tt> is a
value of some type that is in the set of types that are <i>writable</i> to
the particular iterator type of <tt>i</tt>.
</p>
</blockquote>
<p>24.1 p9, add</p>
<blockquote>
<p>
<tt>o</tt> denotes a value of some type that is writable to the
output iterator.
</p>
</blockquote>
<p>Table 73, change</p>
<blockquote>
<pre>
*a = t
</pre>
</blockquote>
<p>to</p>
<blockquote>
<pre>
*r = o
</pre>
</blockquote>
<p>and change</p>
<blockquote>
<pre>
*r++ = t
</pre>
</blockquote>
<p>to</p>
<blockquote>
<pre>
*r++ = o
</pre>
</blockquote>
<p><i>[post-Redmond: Jeremy provided wording]</i></p>
<p><b>Rationale:</b></p>
<p>The LWG considered two options: change all of the language that
seems to imply that output iterators have value types, thus making it
clear that output iterators have no value types, or else define value
types for output iterator consistently. The LWG chose the former
option, because it seems clear that output iterators were never
intended to have value types. This was a deliberate design decision,
and any language suggesting otherwise is simply a mistake.</p>
<p>A future revision of the standard may wish to revisit this design
decision.</p>
<hr>
<a name="325"><h3>325. Misleading text in moneypunct<>::do_grouping</h3></a><p>
<b>Section:</b> 22.2.6.3.2 <a href="lib-locales.html#lib.locale.moneypunct.virtuals"> [lib.locale.moneypunct.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 02 Jul 2001</p>
<p>The Returns clause in 22.2.6.3.2, p3 says about
moneypunct<charT>::do_grouping()
</p>
<blockquote>
Returns: A pattern defined identically as the result of
numpunct<charT>::do_grouping().241)
</blockquote>
<p>Footnote 241 then reads</p>
<blockquote>
This is most commonly the value "\003" (not "3").
</blockquote>
<p>
The returns clause seems to imply that the two member functions must
return an identical value which in reality may or may not be true,
since the facets are usually implemented in terms of struct std::lconv
and return the value of the grouping and mon_grouping, respectively.
The footnote also implies that the member function of the moneypunct
facet (rather than the overridden virtual functions in moneypunct_byname)
most commonly return "\003", which contradicts the C standard which
specifies the value of "" for the (most common) C locale.
</p>
<p><b>Proposed resolution:</b></p>
<p>Replace the text in Returns clause in 22.2.6.3.2, p3 with the following:</p>
<blockquote>
Returns: A pattern defined identically as, but not necessarily
equal to, the result of numpunct<charT>::do_grouping().241)
</blockquote>
<p>and replace the text in Footnote 241 with the following:</p>
<blockquote>
To specify grouping by 3s the value is "\003", not "3".
</blockquote>
<p><b>Rationale:</b></p>
<p>
The fundamental problem is that the description of the locale facet
virtuals serves two purposes: describing the behavior of the base
class, and describing the meaning of and constraints on the behavior
in arbitrary derived classes. The new wording makes that separation a
little bit clearer. The footnote (which is nonnormative) is not
supposed to say what the grouping is in the "C" locale or in any other
locale. It is just a reminder that the values are interpreted as small
integers, not ASCII characters.
</p>
<hr>
<a name="329"><h3>329. vector capacity, reserve and reallocation</h3></a><p>
<b>Section:</b> 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a>, 23.2.4.3 <a href="lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Anthony Williams <b>Date:</b> 13 Jul 2001</p>
<p>
There is an apparent contradiction about which circumstances can cause
a reallocation of a vector in Section 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a> and
section 23.2.4.3 <a href="lib-containers.html#lib.vector.modifiers"> [lib.vector.modifiers]</a>.
</p>
<p>23.2.4.2p5 says:</p>
<blockquote>
Notes: Reallocation invalidates all the references, pointers, and iterators
referring to the elements in the sequence. It is guaranteed that no
reallocation takes place during insertions that happen after a call to
reserve() until the time when an insertion would make the size of the vector
greater than the size specified in the most recent call to reserve().
</blockquote>
<p>Which implies if I do</p>
<pre>
std::vector<int> vec;
vec.reserve(23);
vec.reserve(0);
vec.insert(vec.end(),1);
</pre>
<p>then the implementation may reallocate the vector for the insert,
as the size specified in the previous call to reserve was zero.</p>
<p>However, the previous paragraphs (23.2.4.2, p1-2) state:</p>
<blockquote>
<p>
(capacity) Returns: The total number of elements the vector
can hold without requiring reallocation
</p>
<p>
...After reserve(), capacity() is greater or equal to the
argument of reserve if reallocation happens; and equal to the previous value
of capacity() otherwise...
</p>
</blockquote>
<p>
This implies that vec.capacity() is still 23, and so the insert()
should not require a reallocation, as vec.size() is 0. This is backed
up by 23.2.4.3p1:
</p>
<blockquote>
(insert) Notes: Causes reallocation if the new size is greater than the old
capacity.
</blockquote>
<p>
Though this doesn't rule out reallocation if the new size is less
than the old capacity, I think the intent is clear.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the wording of 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a> paragraph 5 to:</p>
<blockquote>
Notes: Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is guaranteed
that no reallocation takes place during insertions that happen after a
call to reserve() until the time when an insertion would make the size
of the vector greater than the value of capacity().
</blockquote>
<p><i>[Redmond: original proposed resolution was modified slightly. In
the original, the guarantee was that there would be no reallocation
until the size would be greater than the value of capacity() after the
most recent call to reserve(). The LWG did not believe that the
"after the most recent call to reserve()" added any useful
information.]</i></p>
<p><b>Rationale:</b></p>
<p>There was general agreement that, when reserve() is called twice in
succession and the argument to the second invocation is smaller than
the argument to the first, the intent was for the second invocation to
have no effect. Wording implying that such cases have an effect on
reallocation guarantees was inadvertant.</p>
<hr>
<a name="333"><h3>333. does endl imply synchronization with the device?</h3></a><p>
<b>Section:</b> 27.6.2.7 <a href="lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> PremAnand M. Rao <b>Date:</b> 27 Aug 2001</p>
<p>A footnote in 27.6.2.7 <a href="lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a> states:</p>
<blockquote>
[Footnote: The effect of executing cout << endl is to insert a
newline character in the output sequence controlled by cout, then
synchronize it with any external file with which it might be
associated. --- end foonote]
</blockquote>
<p>
Does the term "file" here refer to the external device?
This leads to some implementation ambiguity on systems with fully
buffered files where a newline does not cause a flush to the device.
</p>
<p>
Choosing to sync with the device leads to significant performance
penalties for each call to endl, while not sync-ing leads to
errors under special circumstances.
</p>
<p>
I could not find any other statement that explicitly defined
the behavior one way or the other.
</p>
<p><b>Proposed resolution:</b></p>
<p>Remove footnote 300 from section 27.6.2.7 <a href="lib-iostreams.html#lib.ostream.manip"> [lib.ostream.manip]</a>.</p>
<p><b>Rationale:</b></p>
<p>We already have normative text saying what <tt>endl</tt> does: it
inserts a newline character and calls <tt>flush</tt>. This footnote
is at best redundant, at worst (as this issue says) misleading,
because it appears to make promises about what <tt>flush</tt>
does.</p>
<hr>
<a name="334"><h3>334. map::operator[] specification forces inefficient implementation</h3></a><p>
<b>Section:</b> 23.3.1.2 <a href="lib-containers.html#lib.map.access"> [lib.map.access]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Andrea Griffini <b>Date:</b> 02 Sep 2001</p>
<p>
The current standard describes map::operator[] using a
code example. That code example is however quite
inefficient because it requires several useless copies
of both the passed key_type value and of default
constructed mapped_type instances.
My opinion is that was not meant by the comitee to
require all those temporary copies.
</p>
<p>Currently map::operator[] behaviour is specified as: </p>
<pre>
Returns:
(*((insert(make_pair(x, T()))).first)).second.
</pre>
<p>
This specification however uses make_pair that is a
template function of which parameters in this case
will be deduced being of type const key_type& and
const T&. This will create a pair<key_type,T> that
isn't the correct type expected by map::insert so
another copy will be required using the template
conversion constructor available in pair to build
the required pair<const key_type,T> instance.
</p>
<p>If we consider calling of key_type copy constructor
and mapped_type default constructor and copy
constructor as observable behaviour (as I think we
should) then the standard is in this place requiring
two copies of a key_type element plus a default
construction and two copy construction of a mapped_type
(supposing the addressed element is already present
in the map; otherwise at least another copy
construction for each type).
</p>
<p>A simple (half) solution would be replacing the description with:</p>
<pre>
Returns:
(*((insert(value_type(x, T()))).first)).second.
</pre>
<p>This will remove the wrong typed pair construction that
requires one extra copy of both key and value.</p>
<p>However still the using of map::insert requires temporary
objects while the operation, from a logical point of view,
doesn't require any. </p>
<p>I think that a better solution would be leaving free an
implementer to use a different approach than map::insert
that, because of its interface, forces default constructed
temporaries and copies in this case.
The best solution in my opinion would be just requiring
map::operator[] to return a reference to the mapped_type
part of the contained element creating a default element
with the specified key if no such an element is already
present in the container. Also a logarithmic complexity
requirement should be specified for the operation.
</p>
<p>
This would allow library implementers to write alternative
implementations not using map::insert and reaching optimal
performance in both cases of the addressed element being
present or absent from the map (no temporaries at all and
just the creation of a new pair inside the container if
the element isn't present).
Some implementer has already taken this option but I think
that the current wording of the standard rules that as
non-conforming.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Replace 23.3.1.2 <a href="lib-containers.html#lib.map.access"> [lib.map.access]</a> paragraph 1 with
</p>
<blockquote>
<p>
-1- Effects: If there is no key equivalent to x in the map, inserts
value_type(x, T()) into the map.
</p>
<p>
-2- Returns: A reference to the mapped_type corresponding to x in *this.
</p>
<p>
-3- Complexity: logarithmic.
</p>
</blockquote>
<p><i>[This is the second option mentioned above. Howard provided
wording. We may also wish to have a blanket statement somewhere in
clause 17 saying that we do not intend the semantics of sample code
fragments to be interpreted as specifing exactly how many copies are
made. See issue <a href="lwg-active.html#98">98</a> for a similar problem.]</i></p>
<p><b>Rationale:</b></p>
<p>
This is the second solution described above; as noted, it is
consistent with existing practice.
</p>
<p>Note that we now need to specify the complexity explicitly, because
we are no longer defining <tt>operator[]</tt> in terms of
<tt>insert</tt>.</p>
<hr>
<a name="336"><h3>336. Clause 17 lack of references to deprecated headers</h3></a><p>
<b>Section:</b> 17 <a href="lib-intro.html#lib.library"> [lib.library]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Detlef Vollmann <b>Date:</b> 05 Sep 2001</p>
<p>From c++std-edit-873:</p>
<p>17.4.1.2 <a href="lib-intro.html#lib.headers"> [lib.headers]</a>, Table 11. In this table, the header
<strstream> is missing.</p>
<p>This shows a general problem: The whole clause 17 refers quite
often to clauses 18 through 27, but D.7 is also a part of the standard
library (though a deprecated one).</p>
<p><b>Proposed resolution:</b></p>
<p><i>[Redmond: The LWG agrees that <strstream> should be added
to table 11. A review is needed to determine whether there are any
other places in clause 17 where clause D material should be referred
to. Beman will review clause 17.]</i></p>
<p><i>[Curaçao: Beman emailed wording to Matt, but not in time for the
pre-meeting mailing.]</i></p>
<hr>
<a name="338"><h3>338. is whitespace allowed between `-' and a digit?</h3></a><p>
<b>Section:</b> 22.2 <a href="lib-locales.html#lib.locale.categories"> [lib.locale.categories]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 17 Sep 2001</p>
<p>
From Stage 2 processing in 22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>, p8 and 9 (the
original text or the text corrected by the proposed resolution of
issue <a href="lwg-defects.html#221">221</a>) it seems clear that no whitespace is allowed
within a number, but 22.2.3.1 <a href="lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a>, p2, which gives the
format for integer and floating point values, says that whitespace is
optional between a plusminus and a sign.
</p>
<p>
The text needs to be clarified to either consistently allow or
disallow whitespace between a plusminus and a sign. It might be
worthwhile to consider the fact that the C library stdio facility does
not permit whitespace embedded in numbers and neither does the C or
C++ core language (the syntax of integer-literals is given in 2.13.1 <a href="lex.html#lex.icon"> [lex.icon]</a>, that of floating-point-literals in 2.13.3 <a href="lex.html#lex.fcon"> [lex.fcon]</a> of the C++ standard).
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the first part of 22.2.3.1 <a href="lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a> paragraph 2 from:</p>
<blockquote>
<p>
The syntax for number formats is as follows, where <tt>digit</tt>
represents the radix set specified by the <tt>fmtflags</tt> argument
value, <tt>whitespace</tt> is as determined by the facet
<tt>ctype<charT></tt> (22.2.1.1), and <tt>thousands-sep</tt> and
<tt>decimal-point</tt> are the results of corresponding
<tt>numpunct<charT></tt> members. Integer values have the
format:
</p>
<pre>
integer ::= [sign] units
sign ::= plusminus [whitespace]
plusminus ::= '+' | '-'
units ::= digits [thousands-sep units]
digits ::= digit [digits]
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<p>
The syntax for number formats is as follows, where <tt>digit</tt>
represents the radix set specified by the <tt>fmtflags</tt> argument
value, and <tt>thousands-sep</tt> and <tt>decimal-point</tt> are the
results of corresponding <tt>numpunct<charT></tt> members.
Integer values have the format:
</p>
<pre>
integer ::= [sign] units
sign ::= plusminus
plusminus ::= '+' | '-'
units ::= digits [thousands-sep units]
digits ::= digit [digits]
</pre>
</blockquote>
<p><b>Rationale:</b></p>
<p>It's not clear whether the format described in 22.2.3.1 <a href="lib-locales.html#lib.locale.numpunct"> [lib.locale.numpunct]</a> paragraph 2 has any normative weight: nothing in the
standard says how, or whether, it's used. However, there's no reason
for it to differ gratuitously from the very specific description of
numeric processing in 22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a>. The proposed
resolution removes all mention of "whitespace" from that format.</p>
<hr>
<a name="339"><h3>339. definition of bitmask type restricted to clause 27</h3></a><p>
<b>Section:</b> 22.2.1 <a href="lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a>, 17.3.2.1.2 <a href="lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 17 September 2001</p>
<p>
The ctype_category::mask type is declared to be an enum in 22.2.1 <a href="lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a> with p1 then stating that it is a bitmask type, most
likely referring to the definition of bitmask type in 17.3.2.1.2 <a href="lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a>, p1. However, the said definition only applies to
clause 27, making the reference in 22.2.1 somewhat dubious.
</p>
<p><b>Proposed resolution:</b></p>
<p>Clarify 17.3.2.1.2, p1 by changing the current text from</p>
<blockquote>
Several types defined in clause 27 are bitmask types. Each bitmask type
can be implemented as an enumerated type that overloads certain operators,
as an integer type, or as a bitset (23.3.5 <a href="lib-containers.html#lib.template.bitset"> [lib.template.bitset]</a>).
</blockquote>
<p>to read</p>
<blockquote>
Several types defined in clauses lib.language.support through
lib.input.output and Annex D are bitmask types. Each bitmask type can
be implemented as an enumerated type that overloads certain operators,
as an integer type, or as a bitset (lib.template.bitset).
</blockquote>
<p>
Additionally, change the definition in 22.2.1 to adopt the same
convention as in clause 27 by replacing the existing text with the
following (note, in particluar, the cross-reference to 17.3.2.1.2 in
22.2.1, p1):
</p>
<blockquote>
<p>22.2.1 The ctype category [lib.category.ctype]</p>
<pre>
namespace std {
class ctype_base {
public:
typedef <b><i>T</i></b> mask;
// numeric values are for exposition only.
static const mask space = 1 << 0;
static const mask print = 1 << 1;
static const mask cntrl = 1 << 2;
static const mask upper = 1 << 3;
static const mask lower = 1 << 4;
static const mask alpha = 1 << 5;
static const mask digit = 1 << 6;
static const mask punct = 1 << 7;
static const mask xdigit = 1 << 8;
static const mask alnum = alpha | digit;
static const mask graph = alnum | punct;
};
}
</pre>
<p>The type <tt>mask</tt> is a bitmask type (17.3.2.1.2 <a href="lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a>).</p>
</blockquote>
<p><i>[Curaçao: The LWG notes that T above should be bold-italics to be
consistent with the rest of the standard.]</i></p>
<hr>
<a name="340"><h3>340. interpretation of <tt>has_facet<Facet>(loc)</tt>
</h3></a><p>
<b>Section:</b> 22.1.1.1.1 <a href="lib-locales.html#lib.locale.category"> [lib.locale.category]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 18 Sep 2001</p>
<p>
It's unclear whether 22.1.1.1.1, p3 says that
<tt>has_facet<Facet>(loc)</tt> returns true for any <tt>Facet</tt>
from Table 51 or whether it includes Table 52 as well:
</p>
<blockquote>
For any locale <tt>loc</tt> either constructed, or returned by
locale::classic(), and any facet <tt>Facet</tt> that is a member of a
standard category, <tt>has_facet<Facet>(loc)</tt> is true. Each
locale member function which takes a <tt>locale::category</tt>
argument operates on the corresponding set of facets.
</blockquote>
<p>
It seems that it comes down to which facets are considered to be members of a
standard category. Intuitively, I would classify all the facets in Table 52 as
members of their respective standard categories, but there are an unbounded set
of them...
</p>
<p>
The paragraph implies that, for instance, <tt>has_facet<num_put<C,
OutputIterator> >(loc)</tt> must always return true. I don't think that's
possible. If it were, then <tt>use_facet<num_put<C, OutputIterator>
>(loc)</tt> would have to return a reference to a distinct object for each
valid specialization of <tt>num_put<C, OutputIteratory></tt>, which is
clearly impossible.
</p>
<p>
On the other hand, if none of the facets in Table 52 is a member of a standard
category then none of the locale member functions that operate on entire
categories of facets will work properly.
</p>
<p>
It seems that what p3 should mention that it's required (permitted?)
to hold only for specializations of <tt>Facet</tt> from Table 52 on
<tt>C</tt> from the set { <tt>char</tt>, <tt>wchar_t</tt> }, and
<tt>InputIterator</tt> and <tt>OutputIterator</tt> from the set of
{
{i,o}<tt>streambuf_iterator</tt><{<tt>char</tt>,<tt>wchar_t</tt>}<tt>></tt>
}.
</p>
<p><b>Proposed resolution:</b></p>
<p>In 22.1.1.1.1 <a href="lib-locales.html#lib.locale.category"> [lib.locale.category]</a>, paragraph 3, change
"that is a member of a standard category" to "shown in Table 51".</p>
<p><b>Rationale:</b></p>
<p>The facets in Table 52 are an unbounded set. Locales should not be
required to contain an infinite number of facets.</p>
<p>It's not necessary to talk about which values of InputIterator and
OutputIterator must be supported. Table 51 already contains a
complete list of the ones we need.</p>
<hr>
<a name="341"><h3>341. Vector reallocation and swap</h3></a><p>
<b>Section:</b> 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Anthony Williams <b>Date:</b> 27 Sep 2001</p>
<p>It is a common idiom to reduce the capacity of a vector by swapping it with
an empty one:</p>
<pre>
std::vector<SomeType> vec;
// fill vec with data
std::vector<SomeType>().swap(vec);
// vec is now empty, with minimal capacity
</pre>
<p>However, the wording of 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a>paragraph 5 prevents
the capacity of a vector being reduced, following a call to
reserve(). This invalidates the idiom, as swap() is thus prevented
from reducing the capacity. The proposed wording for issue <a href="lwg-active.html#329">329</a> does not affect this. Consequently, the example above
requires the temporary to be expanded to cater for the contents of
vec, and the contents be copied across. This is a linear-time
operation.</p>
<p>However, the container requirements state that swap must have constant
complexity (23.1 <a href="lib-containers.html#lib.container.requirements"> [lib.container.requirements]</a> note to table 65).</p>
<p>This is an important issue, as reallocation affects the validity of
references and iterators.</p>
<p>If the wording of 23.2.4.2p5 is taken to be the desired intent, then
references and iterators remain valid after a call to swap, if they refer to
an element before the new end() of the vector into which they originally
pointed, in which case they refer to the element at the same index position.
Iterators and references that referred to an element whose index position
was beyond the new end of the vector are invalidated.</p>
<p>If the note to table 65 is taken as the desired intent, then there are two
possibilities with regard to iterators and references:</p>
<ol>
<li>All Iterators and references into both vectors are invalidated.</li>
<li>Iterators and references into either vector remain valid, and remain
pointing to the same element. Consequently iterators and references that
referred to one vector now refer to the other, and vice-versa.</li>
</ol>
<p><b>Proposed resolution:</b></p>
<p>Add a new paragraph after 23.2.4.2 <a href="lib-containers.html#lib.vector.capacity"> [lib.vector.capacity]</a> paragraph 5:</p>
<blockquote>
<pre>
void swap(vector<T,Allocator>& x);
</pre>
<p>
<b>Effects:</b> Exchanges the contents and capacity() of <tt>*this</tt>
with that of <tt>x</tt>.</p>
<p>
<b>Complexity:</b> Constant time.</p>
</blockquote>
<p><i>[This solves the problem reported for this issue. We may also
have a problem with a circular definition of swap() for other
containers.]</i></p>
<p><b>Rationale:</b></p>
<p>
swap should be constant time. The clear intent is that it should just
do pointer twiddling, and that it should exchange all properties of
the two vectors, including their reallocation guarantees.
</p>
<hr>
<a name="342"><h3>342. seek and eofbit</h3></a><p>
<b>Section:</b> 27.6.1.3 <a href="lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Howard Hinnant <b>Date:</b> 09 Oct 201</p>
<p>I think we have a defect.</p>
<p>According to lwg issue <a href="lwg-defects.html#60">60</a> which is now a dr, the
description of seekg in 27.6.1.3 <a href="lib-iostreams.html#lib.istream.unformatted"> [lib.istream.unformatted]</a> paragraph 38 now looks
like:</p>
<blockquote>
Behaves as an unformatted input function (as described in 27.6.1.3,
paragraph 1), except that it does not count the number of characters
extracted and does not affect the value returned by subsequent calls to
gcount(). After constructing a sentry object, if fail() != true,
executes rdbuf()­>pubseekpos( pos).
</blockquote>
<p>And according to lwg issue <a href="lwg-defects.html#243">243</a> which is also now a dr,
27.6.1.3, paragraph 1 looks like:</p>
<blockquote>
Each unformatted input function begins execution by constructing an
object of class sentry with the default argument noskipws (second)
argument true. If the sentry object returns true, when converted to a
value of type bool, the function endeavors to obtain the requested
input. Otherwise, if the sentry constructor exits by throwing an
exception or if the sentry object returns false, when converted to a
value of type bool, the function returns without attempting to obtain
any input. In either case the number of extracted characters is set to
0; unformatted input functions taking a character array of non-zero
size as an argument shall also store a null character (using charT())
in the first location of the array. If an exception is thrown during
input then ios::badbit is turned on in *this'ss error state. If
(exception()&badbit)!= 0 then the exception is rethrown. It also counts
the number of characters extracted. If no exception has been thrown it
ends by storing the count in a member object and returning the value
specified. In any event the sentry object is destroyed before leaving
the unformatted input function.
</blockquote>
<p>And finally 27.6.1.1.2/5 says this about sentry:</p>
<blockquote>
If, after any preparation is completed, is.good() is true, ok_ != false
otherwise, ok_ == false.
</blockquote>
<p>
So although the seekg paragraph says that the operation proceeds if
!fail(), the behavior of unformatted functions says the operation
proceeds only if good(). The two statements are contradictory when only
eofbit is set. I don't think the current text is clear which condition
should be respected.
</p>
<p><b>Further discussion from Redmond:</b></p>
<p>PJP: It doesn't seem quite right to say that <tt>seekg</tt> is
"unformatted". That makes specific claims about sentry that
aren't quite appropriate for seeking, which has less fragile failure
modes than actual input. If we do really mean that it's unformatted
input, it should behave the same way as other unformatted input. On
the other hand, "principle of least surprise" is that seeking from EOF
ought to be OK.</p>
<p>Dietmar: nothing should depend on eofbit. Eofbit should only be
examined by the user to determine why something failed.</p>
<p><i>[Taken from c++std-lib-8873, c++std-lib-8874, c++std-lib-8876]</i></p>
<p><b>Proposed resolution:</b></p>
<p><i>[Howard will do a survey to find out if there are any other
places where we have a problem, where the difference between
<tt>fail()</tt> and <tt>!good()</tt> is important.]</i></p>
<hr>
<a name="347"><h3>347. locale::category and bitmask requirements</h3></a><p>
<b>Section:</b> 22.1.1.1.1 <a href="lib-locales.html#lib.locale.category"> [lib.locale.category]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> P.J. Plauger, Nathan Myers <b>Date:</b> 23 Oct 2001</p>
<p>
In 22.1.1.1.1 <a href="lib-locales.html#lib.locale.category"> [lib.locale.category]</a> paragraph 1, the category members
are described as bitmask elements. In fact, the bitmask requirements
in 17.3.2.1.2 <a href="lib-intro.html#lib.bitmask.types"> [lib.bitmask.types]</a> don't seem quite right: <tt>none</tt>
and <tt>all</tt> are bitmask constants, not bitmask elements.</p>
<p>In particular, the requirements for <tt>none</tt> interact poorly
with the requirement that the LC_* constants from the C library must
be recognizable as C++ locale category constants. LC_* values should
not be mixed with these values to make category values.</p>
<p>We have two options for the proposed resolution. Informally:
option 1 removes the requirement that LC_* values be recognized as
category arguments. Option 2 changes the category type so that this
requirement is implementable, by allowing <tt>none</tt> to be some
value such as 0x1000 instead of 0.</p>
<p>Nathan writes: "I believe my proposed resolution [Option 2] merely
re-expresses the status quo more clearly, without introducing any
changes beyond resolving the DR.</p>
<p><b>Proposed resolution:</b></p>
<p>
<b>Option 1:</b> <br>
Replace the first two paragraphs of 22.1.1.1 <a href="lib-locales.html#lib.locale.types"> [lib.locale.types]</a> with:</p>
<blockquote>
<pre>
typedef int category;
</pre>
<p>Valid category values include the <tt>locale</tt> member bitmask
elements <tt>collate</tt>, <tt>ctype</tt>, <tt>monetary</tt>,
<tt>numeric</tt>, <tt>time</tt>, and <tt>messages</tt>, each of which
represents a single locale category. In addition, <tt>locale</tt> member
bitmask constant <tt>none</tt> is defined as zero and represents no
category. And locale member bitmask constant <tt>all</tt> is defined such that
the expression</p>
<pre>
(collate | ctype | monetary | numeric | time | messages | all) == all
</pre>
<p>
is <tt>true</tt>, and represents the union of all categories. Further
the expression <tt>(X | Y)</tt>, where <tt>X</tt> and <tt>Y</tt> each
represent a single category, represents the union of the two
categories.
</p>
<p>
<tt>locale</tt> member functions expecting a <tt>category</tt>
argument require one of the <tt>category</tt> values defined above, or
the union of two or more such values. Such a <tt>category</tt>
argument identifies a set of locale categories. Each locale category,
in turn, identifies a set of locale facets, including at least those
shown in Table 51:
</p>
</blockquote>
<p>
<b>Option 2:</b> <br>
Replace the first paragraph of 22.1.1.1 <a href="lib-locales.html#lib.locale.types"> [lib.locale.types]</a> with:</p>
<blockquote>
<p>
Valid category values include the enumerated values. In addition, the
result of applying commutative operators | and & to any two valid
values is valid, and results in the setwise union and intersection,
respectively, of the argument categories. The values <tt>all</tt> and
<tt>none</tt> are defined such that for any valid value <tt>cat</tt>, the
expressions <tt>(cat | all == all)</tt>, <tt>(cat & all == cat)</tt>,
<tt>(cat | none == cat)</tt> and <tt>(cat & none == none)</tt> are
true. For non-equal values <tt>cat1</tt> and <tt>cat2</tt> of the
remaining enumerated values, <tt>(cat1 & cat2 == none)</tt> is true.
For any valid categories <tt>cat1</tt> and <tt>cat2</tt>, the result
of <tt>(cat1 & ~cat2)</tt> is valid, and equals the setwise union of
those categories found in <tt>cat1</tt> but not found in <tt>cat2</tt>.
[Footnote: it is not required that <tt>all</tt> equal the setwise union
of the other enumerated values; implementations may add extra categories.]
</p>
</blockquote>
<p><i>[Curaçao: need input from locale experts.]</i></p>
<hr>
<a name="348"><h3>348. Minor issue with std::pair operator<</h3></a><p>
<b>Section:</b> 20.2.2 <a href="lib-utilities.html#lib.pairs"> [lib.pairs]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 23 Oct 2001</p>
<p>
The current wording of 20.2.2 [lib.pairs] p6 precludes the use of
operator< on any pair type which contains a pointer.
</p>
<p><b>Proposed resolution:</b></p>
<p>In 20.2.2 <a href="lib-utilities.html#lib.pairs"> [lib.pairs]</a> paragraph 6, replace:</p>
<pre>
Returns: x.first < y.first || (!(y.first < x.first) && x.second <
y.second).
</pre>
<p>With:</p>
<pre>
Returns: std::less<T1>()( x.first, y.first ) ||
(!std::less<T1>()( y.first, x.first) &&
std::less<T2>()( x.second, y.second ) )
</pre>
<p><i>[Curaçao: LWG leaning toward NAD. In favor of the PR is
that it removes a trap for users. Concerns: 1) will break some
small amount of existing code (which define less and operator <
with different behavior), 2) don't have any indication of rationale
for current design (and unwilling to change without knowing
rationale), 3) consistency; pairs of ptrs would behave differenly from
individual pointers.]</i></p>
<hr>
<a name="349"><h3>349. Minor typographical error in ostream_iterator</h3></a><p>
<b>Section:</b> 24.5.2 <a href="lib-iterators.html#lib.ostream.iterator"> [lib.ostream.iterator]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Andy Sawyer <b>Date:</b> 24 Oct 2001</p>
<p>24.5.2 [lib.ostream.iterator] states:</p>
<pre>
[...]
private:
// basic_ostream<charT,traits>* out_stream; exposition only
// const char* delim; exposition only
</pre>
<p>Whilst it's clearly marked "exposition only", I suspect 'delim'
should be of type 'const charT*'.</p>
<p><b>Proposed resolution:</b></p>
<p>
In 24.5.2 <a href="lib-iterators.html#lib.ostream.iterator"> [lib.ostream.iterator]</a>, replace <tt>const char* delim</tt> with
<tt>const charT* delim</tt>.
</p>
<hr>
<a name="350"><h3>350. allocator<>::address</h3></a><p>
<b>Section:</b> 20.4.1.1 <a href="lib-utilities.html#lib.allocator.members"> [lib.allocator.members]</a>, 20.1.5 <a href="lib-utilities.html#lib.allocator.requirements"> [lib.allocator.requirements]</a>, 17.4.1.1 <a href="lib-intro.html#lib.contents"> [lib.contents]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Nathan Myers <b>Date:</b> 25 Oct 2001</p>
<p>See c++std-lib-9006 and c++std-lib-9007. This issue is taken
verbatim from -9007.</p>
<p>
The core language feature allowing definition of operator&() applied
to any non-builtin type makes that operator often unsafe to use in
implementing libraries, including the Standard Library. The result
is that many library facilities fail for legal user code, such as
the fragment</p>
<pre>
class A { private: A* operator&(); };
std::vector<A> aa;
class B { };
B* operator&(B&) { return 0; }
std::vector<B> ba;
</pre>
<p>
In particular, the requirements table for Allocator (Table 32) specifies
no semantics at all for member address(), and allocator<>::address is
defined in terms of unadorned operator &.
</p>
<p><i>[Curaçao: The LWG believes both examples are ill-formed.
The contained type is required to be CopyConstructible (20.1.3), and
that includes the requirement that &t return the usual types and
values. Since the CopyConstructible requirements appear to have been
written to deal with the concerns of this issue, the LWG feels it is
NAD unless someone can come up with a well-formed example exhibiting a
problem.]</i></p>
<p><b>Proposed resolution:</b></p>
<p>
In 20.4.1.1, Change the definition of allocator<>::address from:</p>
<blockquote>
Returns: &x
</blockquote>
<p>to:</p>
<p>
Returns: The value that the built in operator&(x) would return if not
overloaded.
</p>
<p>
In 20.1.5, Table 32, add to the Notes column of the a.address(r) and
a.address(s) lines, respectively:
</p>
<pre>
allocator<T>::address(r)
allocator<T>::address(s)
</pre>
<p>In addition, in clause 17.4.1.1, add a statement:</p>
<blockquote>
The Standard Library does not apply operator& to any type for which
operator& may be overloaded.
</blockquote>
<p><i>[Curaçao: If the issues isn't NAD, suggest changing "if not
overloaded" to "ignoring all overloads".]</i></p>
<p><b>Rationale:</b></p>
<p>The obvious implementations for std::allocator<>::address are</p>
<pre>
T* reinterpret_cast<T*>(&static_cast<char&>(o));
</pre>
<p>and</p>
<pre>
T const* reinterpret_cast<T const*>(&static_cast<char const&>(o));
</pre>
<p>
but to define them formally in terms of reinterpret_cast<> seems
to introduce semantic difficulties best avoided. Using a.address()
should not introduce unspecified or implementation-defined semantics
into a user program.</p>
<hr>
<a name="352"><h3>352. missing fpos requirements</h3></a><p>
<b>Section:</b> 21.1.2 <a href="lib-strings.html#lib.char.traits.typedefs"> [lib.char.traits.typedefs]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 2 Dec 2001</p>
<p>
<i>(1)</i>
There are no requirements on the <tt>stateT</tt> template parameter of
<tt>fpos</tt> listed in 27.4.3. The interface appears to require that
the type be at least Assignable and CopyConstructible (27.4.3.1, p1),
and I think also DefaultConstructible (to implement the operations in
Table 88).
</p>
<p>
21.1.2, p3, however, only requires that
<tt>char_traits<charT>::state_type</tt> meet the requirements of
CopyConstructible types.
</p>
<p>
<i>(2)</i>
Additionally, the <tt>stateT</tt> template argument has no
corresponding typedef in fpos which might make it difficult to use in
generic code.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Modify 21.1.2, p4 from
</p>
<p>
Requires: <tt>state_type</tt> shall meet the requirements of
CopyConstructible types (20.1.3).
</p>
<p>
Requires: state_type shall meet the requirements of Assignable
(23.1, p4), CopyConstructible (20.1.3), and
DefaultConstructible (20.1.4) types.
</p>
<p>
Add to the definition of the fpos class template the following member:
</p>
<pre>
typedef stateT state_type;
</pre>
<p>
and add to 27.4.3.1 a paragraph with the following text:
</p>
<pre>
typedef stateT state_type;
</pre>
<p>
Requires: <tt>state_type</tt> shall meet the requirements of
Assignable (23.1, p4), CopyConstructible (20.1.3), and
DefaultConstructible (20.1.4) types.
</p>
<p><i>[Curaçao: The LWG feels this is two issues, as indicated
above. The first is a defect; more I/O experts need to review
the PR. The second is questionable; who would use it? Unless
motivation is provided, the second should be considered NAD.]</i></p>
<hr>
<a name="354"><h3>354. Associative container lower/upper bound requirements</h3></a><p>
<b>Section:</b> 23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#Ready">Ready</a> <b>Submitter:</b> Hans Aberg <b>Date:</b> 17 Dec 2001</p>
<p>
Discussions in the thread "Associative container lower/upper bound
requirements" on comp.std.c++ suggests that there is a defect in the
C++ standard, Table 69 of section 23.1.2, "Associative containers",
[lib.associative.reqmts]. It currently says:</p>
<blockquote>
<p>
a.find(k): returns an iterator pointing to an element with the key equivalent to
k, or a.end() if such an element is not found.
</p>
<p>
a.lower_bound(k): returns an iterator pointing to the first element with
key not less than k.
</p>
<p>
a.upper_bound(k): returns an iterator pointing to the first element with
key greater than k.
</p>
</blockquote>
<p>
We have "or a.end() if such an element is not found" for
<tt>find</tt>, but not for <tt>upper_bound</tt> or
<tt>lower_bound</tt>. As the text stands, one would be forced to
insert a new element into the container and return an iterator to that
in case the sought iterator does not exist, which does not seem to be
the intention (and not possible with the "const" versions).
</p>
<p><b>Proposed resolution:</b></p>
<p>Change Table 69 of section 23.1.2 <a href="lib-containers.html#lib.associative.reqmts"> [lib.associative.reqmts]</a> indicated entries
to:</p>
<blockquote>
<p>
a.lower_bound(k): returns an iterator pointing to the first element with
key not less than k, or a.end() if such an element is not found.
</p>
<p>
a.upper_bound(k): returns an iterator pointing to the first element with
key greater than k, or a.end() if such an element is not found.
</p>
</blockquote>
<p><i>[Curaçao: LWG reviewed PR.]</i></p>
<hr>
<a name="355"><h3>355. Operational semantics for a.back()</h3></a><p>
<b>Section:</b> 23.1.1 <a href="lib-containers.html#lib.sequence.reqmts"> [lib.sequence.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#Review">Review</a> <b>Submitter:</b> Yaroslav Mironov <b>Date:</b> 23 Jan 2002</p>
<p>Table 68 "Optional Sequence Operations" in 23.1.1/12
specifies operational semantics for "a.back()" as
"*--a.end()", which may be ill-formed <i>[because calling
operator-- on a temporary (the return) of a built-in type is
ill-formed]</i>, provided a.end() returns a simple pointer rvalue
(this is almost always the case for std::vector::end(), for
example). Thus, the specification is not only incorrect, it
demonstrates a dangerous construct: "--a.end()" may
successfully compile and run as intended, but after changing the type
of the container or the mode of compilation it may produce
compile-time error. </p>
<p><b>Proposed resolution:</b></p>
<p>Change the specification in table 68 "Optional Sequence
Operations" in 23.1.1/12 for "a.back()" from</p>
<blockquote>
*--a.end()
</blockquote>
<p>to</p>
<blockquote>
<p>*a.rbegin()</p>
</blockquote>
<p>and the specification for "a.pop_back()" from</p>
<blockquote>
a.erase(--a.end())
</blockquote>
<p>to</p>
<blockquote>
<p>a.erase(rbegin())</p>
</blockquote>
<p><i>[Curaçao: LWG changed PR from "{ X::iterator tmp =
a.end(); return *--tmp; }" to "*a.rbegin()", and from
"{ X::iterator tmp = a.end(); a.erase(--tmp); }" to
"a.erase(rbegin())".]</i></p>
<p><i>[There is a second possible defect; table 68 "Optional
Sequence Operations" in the "Operational Semantics"
column uses operations present only in the "Reversible
Container" requirements, yet there is no stated dependency
between these separate requirements tables. Ask in Santa Cruz if the
LWG would like a new issue opened.]</i></p>
<hr>
<a name="356"><h3>356. Meaning of ctype_base::mask enumerators</h3></a><p>
<b>Section:</b> 22.2.1 <a href="lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Matt Austern <b>Date:</b> 23 Jan 2002</p>
<p>What should the following program print?</p>
<pre>
#include <locale>
#include <iostream>
class my_ctype : public std::ctype<char>
{
typedef std::ctype<char> base;
public:
my_ctype(std::size_t refs = 0) : base(my_table, false, refs)
{
std::copy(base::classic_table(), base::classic_table() + base::table_size,
my_table);
my_table[(unsigned char) '_'] = (base::mask) (base::print | base::space);
}
private:
mask my_table[base::table_size];
};
int main()
{
my_ctype ct;
std::cout << "isspace: " << ct.is(std::ctype_base::space, '_') << " "
<< "isalpha: " << ct.is(std::ctype_base::alpha, '_') << std::endl;
}
</pre>
<p>The goal is to create a facet where '_' is treated as whitespace.</p>
<p>On gcc 3.0, this program prints "isspace: 1 isalpha: 0". On
Microsoft C++ it prints "isspace: 1 isalpha: 1".</p>
<p>
I believe that both implementations are legal, and the standard does not
give enough guidance for users to be able to use std::ctype's
protected interface portably.</p>
<p>
The above program assumes that ctype_base::mask enumerators like
<tt>space</tt> and <tt>print</tt> are disjoint, and that the way to
say that a character is both a space and a printing character is to or
those two enumerators together. This is suggested by the "exposition
only" values in 22.2.1 <a href="lib-locales.html#lib.category.ctype"> [lib.category.ctype]</a>, but it is nowhere specified in
normative text. An alternative interpretation is that the more
specific categories subsume the less specific. The above program
gives the results it does on the Microsoft compiler because, on that
compiler, <tt>print</tt> has all the bits set for each specific
printing character class.
</p>
<p>From the point of view of std::ctype's public interface, there's no
important difference between these two techniques. From the point of
view of the protected interface, there is. If I'm defining a facet
that inherits from std::ctype<char>, I'm the one who defines the
value that table()['a'] returns. I need to know what combination of
mask values I should use. This isn't so very esoteric: it's exactly
why std::ctype has a protected interface. If we care about users
being able to write their own ctype facets, we have to give them a
portable way to do it.
</p>
<p>
Related reflector messages:
lib-9224, lib-9226, lib-9229, lib-9270, lib-9272, lib-9273, lib-9274,
lib-9277, lib-9279.
</p>
<p>Issue <a href="lwg-active.html#339">339</a> is related, but not identical. The
proposed resolution if issue <a href="lwg-active.html#339">339</a> says that
ctype_base::mask must be a bitmask type. It does not say that the
ctype_base::mask elements are bitmask elements, so it doesn't
directly affect this issue.</p>
<p><b>Proposed resolution:</b></p>
<p>Informally, we have three choices:</p>
<ol>
<li>Require that the enumerators are disjoint (except for alnum and
graph)</li>
<li>Require that the enumerators are not disjoint, and specify which
of them subsume which others. (e.g. mandate that lower includes alpha
and print)</li>
<li>Explicitly leave this unspecified, which the result that the above
program is not portable.</li>
</ol>
<p>Either of the first two options is just as good from the standpoint
of portability. Either one will require some implementations to
change.</p>
<hr>
<a name="357"><h3>357. <cmath> float functions cannot return HUGE_VAL</h3></a><p>
<b>Section:</b> 26.5 <a href="lib-numerics.html#lib.c.math"> [lib.c.math]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a> <b>Submitter:</b> Ray Lischner <b>Date:</b> 26 Feb 2002</p>
<p>
The float versions of the math functions have no meaningful value to return
for a range error. The long double versions have a value they can return,
but it isn't necessarily the most reasonable value.
</p>
<p>
Section 26.5 [lib.c.math], paragraph 5, says that C++ "adds float and long
double overloaded versions of these functions, with the same semantics,"
referring to the math functions from the C90 standard.
</p>
<p>
The C90 standard, in section 7.5.1, paragraph 3, says that functions return
"the value of the macro HUGE_VAL" when they encounter a range error.
Section 7.5, paragraph 2, defines HUGE_VAL as a macro that "expands to a
positive double expression, not necessarily representable as a float."
</p>
<p>
Therefore, the float versions of the math functions have no way to
signal a range error. <i>[Curaçao: The LWG notes that this isn't
strictly correct, since errno is set.]</i> The semantics require that they
return HUGE_VAL, but they cannot because HUGE_VAL might not be
representable as a float.
</p>
<p>
The problem with long double functions is less severe because HUGE_VAL is
representable as a long double. On the other hand, it might not be a "huge"
long double value, and might fall well within the range of normal return
values for a long double function. Therefore, it does not make sense for a
long double function to return a double (HUGE_VAL) for a range error.
</p>
<p><b>Proposed resolution:</b></p>
<p>Curaçao: C99 was faced with a similar problem, which they fixed by
adding HUGE_VALF and HUGE_VALL in addition to HUGE_VAL.</p>
<p>C++ must also fix, but it should be done in the context of the
general C99 based changes to C++, not via DR. Thus the LWG in Curaçao
felt the resolution should be NAD, FUTURE, but the issue is being held
open for one more meeting to ensure LWG members not present during the
discussion concur.</p>
<hr>
<a name="358"><h3>358. interpreting <tt>thousands_sep</tt> after a <tt>decimal_point</tt>
</h3></a><p>
<b>Section:</b> 22.2.2.1.2 <a href="lib-locales.html#lib.facet.num.get.virtuals"> [lib.facet.num.get.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p>
<p>
I don't think <tt>thousands_sep</tt> is being treated correctly after
decimal_point has been seen. Since grouping applies only to the
integral part of the number, the first such occurrence should, IMO,
terminate Stage 2. (If it does not terminate it, then 22.2.2.1.2, p12
and 22.2.3.1.2, p3 need to explain how <tt>thousands_sep</tt> is to be
interpreted in the fractional part of a number.)
</p>
<p>
The easiest change I can think of that resolves this issue would be
something like below.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change the first sentence of 22.2.2.1.2, p9 from
</p>
<blockquote>
If discard is true then the position of the character is
remembered, but the character is otherwise ignored. If it is not
discarded, then a check is made to determine if c is allowed as
the next character of an input field of the conversion specifier
returned by stage 1. If so it is accumulated.
</blockquote>
<p>to</p>
<blockquote>
If <tt>discard</tt> is true, then if <tt>'.'</tt> has not yet been
accumulated, then the position of the character is remembered, but
the character is otherwise ignored. Otherwise, if <tt>'.'</tt> has
already been accumulated, the character is discarded and Stage 2
terminates. ...
</blockquote>
<hr>
<a name="359"><h3>359. num_put<>::do_put (..., bool) undocumented</h3></a><p>
<b>Section:</b> 22.2.2.2.1 <a href="lib-locales.html#lib.facet.num.put.members"> [lib.facet.num.put.members]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p>
<p>22.2.2.2.1, p1:</p>
<pre>
iter_type put (iter_type out, ios_base& str, char_type fill,
bool val) const;
...
1 Returns: do_put (out, str, fill, val).
</pre>
<p>AFAICS, the behavior of do_put (..., bool) is not documented anywhere,
however, 22.2.2.2.2, p23:</p>
<blockquote>
<pre>
iter_type put (iter_type out, ios_base& str, char_type fill,
bool val) const;
</pre>
Effects: If (str.flags() & ios_base::boolalpha) == 0 then do
out = do_put(out, str, fill, (int)val)
Otherwise do
<pre>
string_type s =
val ? use_facet<ctype<charT> >(loc).truename()
: use_facet<ctype<charT> >(loc).falsename();
</pre>
and then insert the characters of s into out. <i>out</i>.
</blockquote>
<p>
This means that the bool overload of <tt>do_put()</tt> will never be called,
which contradicts the first paragraph. Perhaps the declaration
should read <tt>do_put()</tt>, and not <tt>put()</tt>?
</p>
<p>
Note also that there is no <b>Returns</b> clause for this function, which
should probably be corrected, just as should the second occurrence
of <i>"out."</i> in the text.
</p>
<p>
I think the least invasive change to fix it would be something like
the following:
</p>
<p><b>Proposed resolution:</b></p>
<p>
In 22.2.2.2.2, p23, make the following changes
</p>
<blockquote>
Replace <tt>put()</tt> with <tt>do_put()</tt> in the declaration
of the member function.
</blockquote>
<blockquote>
Change the <b>Effects</b> clause to a <b>Returns</b> clause (to
avoid the requirement to call <tt>do_put(..., int)</tt> from <tt>
do_put (..., bool))</tt>
like so:
</blockquote>
<blockquote>
23 <b>Returns</b>: If <tt>(str.flags() &
ios_base::boolalpha) == 0</tt> then
<tt>do_put (out, str, fill, (int)val)</tt>
Otherwise the function obtains a string <tt>s</tt> as if by
<pre>
string_type s =
val ? use_facet<ctype<charT> >(loc).truename()
: use_facet<ctype<charT> >(loc).falsename();
</pre>
and then inserts each character <tt>c</tt> of s into out via
<tt>*out++ = c</tt>
and returns <tt>out</tt>.
</blockquote>
<hr>
<a name="360"><h3>360. locale mandates inefficient implementation</h3></a><p>
<b>Section:</b> 22.1.1 <a href="lib-locales.html#lib.locale"> [lib.locale]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p>
<p>
22.1.1, p7 (copied below) allows iostream formatters and extractors
to make assumptions about the values returned from facet members.
However, such assumptions are apparently not guaranteed to hold
in other cases (e.g., when the facet members are being called directly
rather than as a result of iostream calls, or between successive
calls to the same iostream functions with no interevening calls to
<tt>imbue()</tt>, or even when the facet member functions are called
from other member functions of other facets). This restriction
prevents locale from being implemented efficiently.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the first sentence in 22.1.1, p7 from</p>
<blockquote>
In successive calls to a locale facet member function during
a call to an iostream inserter or extractor or a streambuf member
function, the returned result shall be identical. [Note: This
implies that such results may safely be reused without calling
the locale facet member function again, and that member functions
of iostream classes cannot safely call <tt>imbue()</tt>
themselves, except as specified elsewhere. --end note]
</blockquote>
<p>to</p>
<blockquote>
In successive calls to a locale facet member function on a facet
object installed in the same locale, the returned result shall be
identical. ...
</blockquote>
<hr>
<a name="361"><h3>361. num_get<>::do_get (..., void*&) checks grouping</h3></a><p>
<b>Section:</b> 22.2.2.2.2 <a href="lib-locales.html#lib.facet.num.put.virtuals"> [lib.facet.num.put.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Martin Sebor <b>Date:</b> 12 Mar 2002</p>
<p>
22.2.2.2.2, p12 specifies that <tt>thousands_sep</tt> is to be inserted only
for integral types (issue 282 suggests that this should be done for
all arithmetic types).
</p>
<p>
22.2.2.1.2, p12 requires that grouping be checked for all extractors
including that for <tt>void*</tt>.
</p>
<p>
I don't think that's right. <tt>void*</tt> values should not be checked for
grouping, should they? (Although if they should, then <tt>num_put</tt> needs
to write them out, otherwise their extraction will fail.)
</p>
<p><b>Proposed resolution:</b></p>
<p>
Change the first sentence of 22.2.2.2.2, p12 from
</p>
<blockquote>
Digit grouping is checked. That is, the positions of discarded
separators is examined for consistency with
use_facet<numpunct<charT> >(loc).grouping().
If they are not consistent then ios_base::failbit is assigned
to err.
</blockquote>
<p>to</p>
<blockquote>
Except for conversions to void*, digit grouping is checked...
</blockquote>
<hr>
<a name="362"><h3>362. bind1st/bind2nd type safety</h3></a><p>
<b>Section:</b> 20.3.6.2 <a href="lib-utilities.html#lib.bind.1st"> [lib.bind.1st]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Andrew Demkin <b>Date:</b> 26 Apr 2002</p>
<p>
The definition of bind1st() (20.3.6.2 <a href="lib-utilities.html#lib.bind.1st"> [lib.bind.1st]</a>) can result in
the construction of an unsafe binding between incompatible pointer
types. For example, given a function whose first parameter type is
'pointer to T', it's possible without error to bind an argument of
type 'pointer to U' when U does not derive from T:
</p>
<pre>
foo(T*, int);
struct T {};
struct U {};
U u;
int* p;
int* q;
for_each(p, q, bind1st(ptr_fun(foo), &u)); // unsafe binding
</pre>
<p>
The definition of bind1st() includes a functional-style conversion to
map its argument to the expected argument type of the bound function
(see below):
</p>
<pre>
typename Operation::first_argument_type(x)
</pre>
<p>
A functional-style conversion (5.2.3 <a href="expr.html#expr.type.conv"> [expr.type.conv]</a>) is defined to be
semantically equivalent to an explicit cast expression (5.4 <a href="expr.html#expr.cast"> [expr.cast]</a>), which may (according to 5.4, paragraph 5) be interpreted
as a reinterpret_cast, thus masking the error.
</p>
<p>The problem and proposed change also apply to 20.3.6.4 <a href="lib-utilities.html#lib.bind.2nd"> [lib.bind.2nd]</a>.</p>
<p><b>Proposed resolution:</b></p>
<p>
The simplest and most localized change to prevent such errors is to
require bind1st() use a static_cast expression rather than the
functional-style conversion; that is, have bind1st() return:
</p>
<pre>
binder1st<Operation>( op,
static_cast<typename Operation::first_argument_type>(x)).
</pre>
<p>
A more agressive solution is to change the semantics of
functional-style conversions to not permit a reinterpret_cast. For
contexts that require the semantics of reinterpret_cast, the language
may want to require the use of an explicit cast expression such as
'(T) x' or 'reinterpret_cast<T>(x)' and limit the behavior of
the functional notation to match statically-checked and standard
conversions (as defined by 5.2.9 and 4.10, etc.). Although changing
the semantics of functional-style conversions may seem drastic and
does have language-wide ramifications, it has the benefit of better
unifying the conversion rules for user defined types and built-in
types, which can be especially important for generic template
programming.
</p>
<hr>
<a name="363"><h3>363. Missing exception specification in 27.4.2.1.1</h3></a><p>
<b>Section:</b> 27.4.2.1.1 <a href="lib-iostreams.html#lib.ios::failure"> [lib.ios::failure]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 20 May 2002</p>
<p>
The destructor of ios_base::failure should have an empty throw
specification, because the destructor of its base class, exception, is
declared in this way.
</p>
<p><b>Proposed resolution:</b></p>
<p>Change the destructor to</p>
<pre>
virtual ~failure() throw();
</pre>
<hr>
<a name="364"><h3>364. Inconsistent wording in 27.5.2.4.2</h3></a><p>
<b>Section:</b> 27.5.2.4.2 <a href="lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 10 May 2002</p>
<p>
27.5.2.4.2 <a href="lib-iostreams.html#lib.streambuf.virt.buffer"> [lib.streambuf.virt.buffer]</a> paragraph 1 is inconsistent with the Effects
clause for seekoff.
</p>
<p><b>Proposed resolution:</b></p>
<p>
Make this paragraph, the Effects clause for setbuf, consistent in wording
with the Effects clause for seekoff in paragraph 3 by amending paragraph 1
to indicate the purpose of setbuf:
</p>
<p>Original text:</p>
<blockquote>
1 Effects: Performs an operation that is defined separately for each
class derived from basic_streambuf in this clause (27.7.1.3, 27.8.1.4).
</blockquote>
<p>Proposed text:</p>
<blockquote>
1 Effects: Influences stream buffering in a way that is defined separately
for each class derived from basic_streambuf in this clause
(27.7.1.3, 27.8.1.4).
</blockquote>
<hr>
<a name="365"><h3>365. Lack of const-qualification in clause 27</h3></a><p>
<b>Section:</b> 27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 10 May 2002</p>
<p>
None of the following member functions are declared const, but we
believe each should be. See document N1360 for details and rationale.
</p>
<p><b>Proposed resolution:</b></p>
<p>In 27.5.2 and 27.5.2.2.3</p>
<p>Replace</p>
<pre>
streamsize in_avail();
</pre>
<p>with</p>
<pre>
streamsize in_avail() const;
</pre>
<p>In 27.5.2 and 27.5.2.4.3, and 27.8.1.1 and 27.8.1.4</p>
<p>Replace</p>
<pre>
virtual streamsize showmanyc();
</pre>
<p>with</p>
<pre>
virtual streamsize showmanyc() const;
</pre>
<p>In 27.6.1.1 and 27.6.1.3</p>
<p>Replace</p>
<pre>
pos_type tellg();
</pre>
<p>with</p>
<pre>
pos_type tellg() const;
</pre>
<p>This requires additional change, because paragraph 37 describes the
return value in terms of calls to non-const member functions. Either of
the two following solutions would allow tellg to be declared const.</p>
<p>Option 1: Implementers may cast away const-ness, to allow calling the
non-const rdbuf.</p>
<p>In paragraph 37, replace:</p>
<pre>
.... rdbuf()
->pubseekoff(0, cur, in).
</pre>
<p>by</p>
<pre>
.... const_cast<basic_istream<charT, traits>*>(this)->rdbuf()
->pubseekoff(0, cur, in).
</pre>
<p>Option 2: Provide const member functions to do the job. The proposals in
a later section (specifically, the modifications concerning rdbuf
throughout the iostream library) meet most of this need; we would also
need the following addition to basic_streambuf:</p>
<blockquote>
<pre>
basic_streambuf<charT,traits>::pos_type
basic_streambuf<charT,traits>::position(ios_base::openmode mode =
ios_base::in|ios_base::out)
const;
</pre>
<p>Effects: same as calling basic_streambuf::pubseekoff(0, ios base::cur, mode)</p>
</blockquote>
<p>In 27.6.2.1 and 27.6.2.4</p>
<p>Replace</p>
<pre>
pos_type tellp();
</pre>
<p>with</p>
<pre>
pos_type tell() const;
</pre>
<p>This requires additional change; see the discussion for tellg() above.</p>
<p>In 27.8.1.5, 27.8.1.7, 27.8.1.8, 27.8.1.10, 27.8.1.11, and 27.8.1.13</p>
<p>Replace</p>
<pre>
bool is_open();
</pre>
<p>with</p>
<pre>
bool is_open() const;
</pre>
<hr>
<a name="366"><h3>366. Excessive const-qualification</h3></a><p>
<b>Section:</b> 27 <a href="lib-iostreams.html#lib.input.output"> [lib.input.output]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a> <b>Submitter:</b> Walter Brown <b>Date:</b> 10 May 2002</p>
<p>
The following member functions are declared const, yet return non-const
pointers. We believe they are should be changed, because they allow code
that may surprise the user. See document N1360 for details and
rationale.
</p>
<p><b>Proposed resolution:</b></p>
<p>In 27.4.4 and 27.4.4.2</p>
<p>Replace</p>
<pre>
basic_ostream<charT,traits>* tie() const;
</pre>
<p>with</p>
<pre>
basic_ostream<charT,traits>* tie();
const basic_ostream<charT,traits>* tie() const;
</pre>
<p>and replace</p>
<pre>
basic_streambuf<charT,traits>* rdbuf() const;
</pre>
<p>with</p>
<pre>
basic_streambuf<charT,traits>* rdbuf();
const basic_streambuf<charT,traits>* rdbuf() const;
</pre>
<p>In 27.5.2 and 27.5.2.3.1</p>
<p>Replace</p>
<pre>
char_type* eback() const;
</pre>
<p>with</p>
<pre>
char_type* eback();
const char_type* eback() const;
</pre>
<p>Replace</p>
<pre>
char_type gptr() const;
</pre>
<p>with</p>
<pre>
char_type* gptr();
const char_type* gptr() const;
</pre>
<p>Replace</p>
<pre>
char_type* egptr() const;
</pre>
<p>with</p>
<pre>
char_type* egptr();
const char_type* egptr() const;
</pre>
<p>In 27.5.2 and 27.5.2.3.2</p>
<p>Replace</p>
<pre>
char_type* pbase() const;
</pre>
<p>with</p>
<pre>
char_type* pbase();
const char_type* pbase() const;
</pre>
<p>Replace</p>
<pre>
char_type* pptr() const;
</pre>
<p>with</p>
<pre>
char_type* pptr();
const char_type* pptr() const;
</pre>
<p>Replace</p>
<pre>
char_type* epptr() const;
</pre>
<p>with</p>
<pre>
char_type* epptr();
const char_type* epptr() const;
</pre>
<p>In 27.7.2, 27.7.2.2, 27.7.3 27.7.3.2, 27.7.4, and 27.7.6</p>
<p>Replace</p>
<pre>
basic_stringbuf<charT,traits,Allocator>* rdbuf() const;
</pre>
<p>with</p>
<pre>
basic_stringbuf<charT,traits,Allocator>* rdbuf();
const basic_stringbuf<charT,traits,Allocator>* rdbuf() const;
</pre>
<p>In 27.8.1.5, 27.8.1.7, 27.8.1.8, 27.8.1.10, 27.8.1.11, and 27.8.1.13</p>
<p>Replace</p>
<pre>
basic_filebuf<charT,traits>* rdbuf() const;
</pre>
<p>with</p>
<pre>
basic_filebuf<charT,traits>* rdbuf();
const basic_filebuf<charT,traits>* rdbuf() const;
</pre>
<p>----- End of document -----</p>
</body>
</html>
|