File: index.rst

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (2351 lines) | stat: -rw-r--r-- 70,582 bytes parent folder | download
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
+++++++++++++++++++++++++++++++++++++++++++++++++
 The Boost Parameter Library 
+++++++++++++++++++++++++++++++++++++++++++++++++

|(logo)|__

.. |(logo)| image:: ../../../../boost.png
   :alt: Boost

__ ../../../../index.htm

-------------------------------------

:Abstract: Use this library to write functions and class templates
  that can accept arguments by name:

  .. parsed-literal::

    new_window("alert", **_width=10**, **_titlebar=false**);

    smart_ptr<
       Foo 
     , **deleter<Deallocate<Foo> >**
     , **copy_policy<DeepCopy>** > p(new Foo);
    
  Since named arguments can be passed in any order, they are
  especially useful when a function or template has more than one
  parameter with a useful default value.  The library also supports
  *deduced* parameters; that is to say, parameters whose identity
  can be deduced from their types.

.. @jam_prefix.append('''
        project test : requirements <include>. <source>/boost//headers ;''')

.. @example.prepend('''
   #include <boost/parameter.hpp>
   
   namespace test
   {
     BOOST_PARAMETER_NAME(title)
     BOOST_PARAMETER_NAME(width)
     BOOST_PARAMETER_NAME(titlebar)
   
     BOOST_PARAMETER_FUNCTION(
        (int), new_window, tag, (required (title,*)(width,*)(titlebar,*)))
     {
        return 0;
     }
     
     BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter)
     BOOST_PARAMETER_TEMPLATE_KEYWORD(copy_policy)

     template <class T> struct Deallocate {};
     struct DeepCopy {};

     namespace parameter = boost::parameter;
     
     struct Foo {};
     template <class T, class A0, class A1>
     struct smart_ptr
     {
         smart_ptr(Foo*);
     };
   }
   using namespace test;
   int x = ''');

.. @test('compile')


-------------------------------------

:Authors:       David Abrahams, Daniel Wallin
:Contact:       dave@boost-consulting.com, dalwan01@student.umu.se
:Organization:  `Boost Consulting`_
:Date:          $Date: 2005/07/18 20:34:31 $

:Copyright:     Copyright David Abrahams, Daniel Wallin 2005. 
                Distributed under the Boost Software License,
                Version 1.0. (See accompanying file LICENSE_1_0.txt
                or copy at http://www.boost.org/LICENSE_1_0.txt)

.. _`Boost Consulting`: http://www.boost-consulting.com

.. _concepts: http://www.boost.org/more/generic_programming.html#concept

-------------------------------------

.. contents:: **Table of Contents**

.. role:: concept
   :class: concept

.. role:: vellipsis
   :class: vellipsis

.. section-numbering::

-------------------------------------

============
 Motivation
============

In C++, arguments_ are normally given meaning by their positions
with respect to a parameter_ list: the first argument passed maps
onto the first parameter in a function's definition, and so on.
That protocol is fine when there is at most one parameter with a
default value, but when there are even a few useful defaults, the
positional interface becomes burdensome:

* .. compound::

    Since an argument's meaning is given by its position, we have to
    choose an (often arbitrary) order for parameters with default
    values, making some combinations of defaults unusable:

    .. parsed-literal::

      window* new_window(
         char const* name, 
         **int border_width = default_border_width,**
         bool movable = true,
         bool initially_visible = true
         );

      const bool movability = false;
      window* w = new_window("alert box", movability);

    In the example above we wanted to make an unmoveable window
    with a default ``border_width``, but instead we got a moveable
    window with a ``border_width`` of zero.  To get the desired
    effect, we'd need to write:

    .. parsed-literal::

       window* w = new_window(
          "alert box", **default_border_width**, movability);

* .. compound::

    It can become difficult for readers to understand the meaning of
    arguments at the call site::

      window* w = new_window("alert", 1, true, false);

    Is this window moveable and initially invisible, or unmoveable
    and initially visible?  The reader needs to remember the order
    of arguments to be sure.  

* The author of the call may not remember the order of the
  arguments either, leading to hard-to-find bugs.

.. @ignore(3)

-------------------------
Named Function Parameters
-------------------------

.. compound::

  This library addresses the problems outlined above by associating
  each parameter name with a keyword object.  Now users can identify
  arguments by name, rather than by position:

  .. parsed-literal::

    window* w = new_window("alert box", **movable_=**\ false); // OK!

.. @ignore()

---------------------------
Deduced Function Parameters
---------------------------

.. compound::

  A **deduced parameter** can be passed in any position *without*
  supplying an explicit parameter name.  It's not uncommon for a
  function to have parameters that can be uniquely identified based
  on the types of arguments passed.  The ``name`` parameter to
  ``new_window`` is one such example.  None of the other arguments,
  if valid, can reasonably be converted to a ``char const*``.  With
  a deduced parameter interface, we could pass the window name in
  *any* argument position without causing ambiguity:

  .. parsed-literal::

    window* w = new_window(movable_=false, **"alert box"**); // OK!
    window* w = new_window(**"alert box"**, movable_=false); // OK!

  Appropriately used, a deduced parameter interface can free the
  user of the burden of even remembering the formal parameter
  names.

.. @ignore()

--------------------------------
Class Template Parameter Support
--------------------------------

.. compound::

  The reasoning we've given for named and deduced parameter
  interfaces applies equally well to class templates as it does to
  functions.  Using the Parameter library, we can create interfaces
  that allow template arguments (in this case ``shared`` and
  ``Client``) to be explicitly named, like this:

  .. parsed-literal::

    smart_ptr<**ownership<shared>**, **value_type<Client>** > p;

  The syntax for passing named template arguments is not quite as
  natural as it is for function arguments (ideally, we'd be able to
  write ``smart_ptr<ownership=shared,…>``).  This small syntactic
  deficiency makes deduced parameters an especially big win when
  used with class templates:

  .. parsed-literal::

    // *p and q could be equivalent, given a deduced*
    // *parameter interface.*
    smart_ptr<**shared**, **Client**> p;
    smart_ptr<**Client**, **shared**> q;

.. @ignore(2)

==========
 Tutorial
==========

This tutorial shows all the basics—how to build both named- and deduced-parameter
interfaces to function templates and class templates—and several
more advanced idioms as well.

---------------------------
Parameter-Enabled Functions
---------------------------

In this section we'll show how the Parameter library can be used to
build an expressive interface to the `Boost Graph library`__\ 's
|dfs|_ algorithm. [#old_interface]_ 

.. Revisit this

  After laying some groundwork
  and describing the algorithm's abstract interface, we'll show you
  how to build a basic implementation with keyword support.  Then
  we'll add support for default arguments and we'll gradually refine the
  implementation with syntax improvements.  Finally we'll show how to
  streamline the implementation of named parameter interfaces,
  improve their participation in overload resolution, and optimize
  their runtime efficiency.

__ ../../../graph/index.html

.. _dfs: ../../../graph/doc/depth_first_search.html

.. |dfs| replace:: ``depth_first_search``


Headers And Namespaces
======================

Most components of the Parameter library are declared in a
header named for the component.  For example, ::

  #include <boost/parameter/keyword.hpp>

will ensure ``boost::parameter::keyword`` is known to the
compiler.  There is also a combined header,
``boost/parameter.hpp``, that includes most of the library's
components.  For the the rest of this tutorial, unless we say
otherwise, you can use the rule above to figure out which header
to ``#include`` to access any given component of the library.

.. @example.append('''
   using boost::parameter::keyword;
   ''')

.. @test('compile')

Also, the examples below will also be written as if the
namespace alias ::

  namespace parameter = boost::parameter;

.. @ignore()

has been declared: we'll write ``parameter::xxx`` instead of
``boost::parameter::xxx``.

The Abstract Interface to |dfs|
===============================

The Graph library's |dfs| algorithm is a generic function accepting
from one to four arguments by reference.  If all arguments were
required, its signature might be as follows::

   template <
       class Graph, class DFSVisitor, class Index, class ColorMap
   >
   void depth_first_search(
     , Graph const& graph 
     , DFSVisitor visitor
     , typename graph_traits<g>::vertex_descriptor root_vertex
     , IndexMap index_map
     , ColorMap& color);

.. @ignore()

However, most of the parameters have a useful default value, as
shown in the table below.

.. _`parameter table`: 
.. _`default expressions`: 

.. table:: ``depth_first_search`` Parameters

  +----------------+----------+---------------------------------+----------------------------------+
  | Parameter Name | Dataflow | Type                            | Default Value (if any)           |
  +================+==========+=================================+==================================+
  |``graph``       | in       |Model of |IncidenceGraph|_ and   |none - this argument is required. |
  |                |          ||VertexListGraph|_               |                                  |
  |                |          |                                 |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``visitor``     | in       |Model of |DFSVisitor|_           |``boost::dfs_visitor<>()``        |
  +----------------+----------+---------------------------------+----------------------------------+
  |``root_vertex`` | in       |``graph``'s vertex descriptor    |``*vertices(graph).first``        |
  |                |          |type.                            |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``index_map``   | in       |Model of |ReadablePropertyMap|_  |``get(boost::vertex_index,graph)``|
  |                |          |with key type := ``graph``'s     |                                  |
  |                |          |vertex descriptor and value type |                                  |
  |                |          |an integer type.                 |                                  |
  +----------------+----------+---------------------------------+----------------------------------+
  |``color_map``   | in/out   |Model of |ReadWritePropertyMap|_ |an ``iterator_property_map``      |
  |                |          |with key type := ``graph``'s     |created from a ``std::vector`` of |
  |                |          |vertex descriptor type.          |``default_color_type`` of size    |
  |                |          |                                 |``num_vertices(graph)`` and using |
  |                |          |                                 |``index_map`` for the index map.  |
  +----------------+----------+---------------------------------+----------------------------------+

.. |IncidenceGraph| replace:: :concept:`Incidence Graph`
.. |VertexListGraph| replace:: :concept:`Vertex List Graph`
.. |DFSVisitor| replace:: :concept:`DFS Visitor`
.. |ReadablePropertyMap| replace:: :concept:`Readable Property Map`
.. |ReadWritePropertyMap| replace:: :concept:`Read/Write Property Map`

.. _`IncidenceGraph`: ../../../graph/doc/IncidenceGraph.html
.. _`VertexListGraph`: ../../../graph/doc/VertexListGraph.html
.. _`DFSVisitor`: ../../../graph/doc/DFSVisitor.html
.. _`ReadWritePropertyMap`: ../../../property_map/ReadWritePropertyMap.html
.. _`ReadablePropertyMap`: ../../../property_map/ReadablePropertyMap.html

Don't be intimidated by the information in the second and third
columns above.  For the purposes of this exercise, you don't need
to understand them in detail.

Defining the Keywords
=====================

The point of this exercise is to make it possible to call
``depth_first_search`` with named arguments, leaving out any
arguments for which the default is appropriate:

.. parsed-literal::

  graphs::depth_first_search(g, **color_map_=my_color_map**);

.. @ignore()

To make that syntax legal, there needs to be an object called
“\ ``color_map_``\ ” whose assignment operator can accept a
``my_color_map`` argument.  In this step we'll create one such
**keyword object** for each parameter.  Each keyword object will be
identified by a unique **keyword tag type**.  

.. Revisit this

  We're going to define our interface in namespace ``graphs``.  Since
  users need access to the keyword objects, but not the tag types,
  we'll define the keyword objects so they're accessible through
  ``graphs``, and we'll hide the tag types away in a nested
  namespace, ``graphs::tag``.  The library provides a convenient
  macro for that purpose.

We're going to define our interface in namespace ``graphs``.  The
library provides a convenient macro for defining keyword objects::

  #include <boost/parameter/name.hpp>

  namespace graphs
  {
    BOOST_PARAMETER_NAME(graph)    // Note: no semicolon
    BOOST_PARAMETER_NAME(visitor)
    BOOST_PARAMETER_NAME(root_vertex)
    BOOST_PARAMETER_NAME(index_map)
    BOOST_PARAMETER_NAME(color_map)
  }

.. @test('compile')

The declaration of the ``graph`` keyword you see here is
equivalent to::

  namespace graphs 
  {
    namespace tag { struct graph; } // keyword tag type

    namespace // unnamed
    {
      // A reference to the keyword object
      boost::parameter::keyword<tag::graph>& _graph
      = boost::parameter::keyword<tag::graph>::get();
    }
  }

.. @example.prepend('#include <boost/parameter/keyword.hpp>')
.. @test('compile')

It defines a *keyword tag type* named ``tag::graph`` and a *keyword
object* reference named ``_graph``.

This “fancy dance” involving an unnamed namespace and references
is all done to avoid violating the One Definition Rule (ODR)
[#odr]_ when the named parameter interface is used by function
templates that are instantiated in multiple translation
units (MSVC6.x users see `this note`__).

__ `Compiler Can't See References In Unnamed Namespace`_

Writing the Function
====================

Now that we have our keywords defined, the function template
definition follows a simple pattern using the
``BOOST_PARAMETER_FUNCTION`` macro::

  #include <boost/parameter/preprocessor.hpp>

  namespace graphs
  {
    BOOST_PARAMETER_FUNCTION(
        (void),                // 1. parenthesized return type
        depth_first_search,    // 2. name of the function template

        tag,                   // 3. namespace of tag types

        (required (graph, *) ) // 4. one required parameter, and

        (optional              //    four optional parameters, with defaults
          (visitor,           *, boost::dfs_visitor<>()) 
          (root_vertex,       *, *vertices(graph).first) 
          (index_map,         *, get(boost::vertex_index,graph)) 
          (in_out(color_map), *, 
            default_color_map(num_vertices(graph), index_map) ) 
        )
    )
    {
        // ... body of function goes here...
        // use graph, visitor, index_map, and color_map
    }
  }

.. @example.prepend('''
   #include <boost/parameter/name.hpp>

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   namespace boost {

   template <class T = int>
   struct dfs_visitor
   {};

   int vertex_index = 0;

   }''')

.. @test('compile')

The arguments to ``BOOST_PARAMETER_FUNCTION`` are:

1. The return type of the resulting function template.  Parentheses
   around the return type prevent any commas it might contain from
   confusing the preprocessor, and are always required.

2. The name of the resulting function template.

3. The name of a namespace where we can find tag types whose names
   match the function's parameter names.

4. The function signature.  

Function Signatures
===================

Function signatures are described as one or two adjacent
parenthesized terms (a Boost.Preprocessor_ sequence_) describing
the function's parameters in the order in which they'd be expected
if passed positionally.  Any required parameters must come first,
but the ``(required … )`` clause can be omitted when all the
parameters are optional.

.. _Boost.Preprocessor: ../../../preprocessor/index.html

Required Parameters
-------------------

.. compound::

  Required parameters are given first—nested in a ``(required … )``
  clause—as a series of two-element tuples describing each parameter
  name and any requirements on the argument type.  In this case there
  is only a single required parameter, so there's just a single
  tuple:

  .. parsed-literal::

     (required **(graph, \*)** )

  Since ``depth_first_search`` doesn't require any particular type
  for its ``graph`` parameter, we use an asterix to indicate that
  any type is allowed.  Required parameters must always precede any
  optional parameters in a signature, but if there are *no*
  required parameters, the ``(required … )`` clause can be omitted
  entirely.

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(graph)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
   ''')

.. @example.append(') {}')
.. @test('compile')

Optional Parameters
-------------------

.. compound::

  Optional parameters—nested in an ``(optional … )`` clause—are given
  as a series of adjacent *three*\ -element tuples describing the
  parameter name, any requirements on the argument type, *and* and an
  expression representing the parameter's default value:

  .. parsed-literal::

    (optional **\
        (visitor,           \*, boost::dfs_visitor<>()) 
        (root_vertex,       \*, \*vertices(graph).first) 
        (index_map,         \*, get(boost::vertex_index,graph)) 
        (in_out(color_map), \*, 
          default_color_map(num_vertices(graph), index_map) )**
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   namespace boost
   {
     int vertex_index = 0;

     template <class T = int>
     struct dfs_visitor
     {};
   }

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
     (required (graph, *))
   ''')

.. @example.append(') {}')
.. @test('compile')

Handling “Out” Parameters
-------------------------

.. compound::

  Within the function body, a parameter name such as ``visitor`` is
  a *C++ reference*, bound either to an actual argument passed by
  the caller or to the result of evaluating a default expression.
  In most cases, parameter types are of the form ``T const&`` for
  some ``T``.  Parameters whose values are expected to be modified,
  however, must be passed by reference to *non*\ -``const``.  To
  indicate that ``color_map`` is both read and written, we wrap
  its name in ``in_out(…)``:

  .. parsed-literal::

    (optional
        (visitor,            \*, boost::dfs_visitor<>()) 
        (root_vertex,        \*, \*vertices(graph).first) 
        (index_map,          \*, get(boost::vertex_index,graph)) 
        (**in_out(color_map)**, \*, 
          default_color_map(num_vertices(graph), index_map) )
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   namespace boost
   {
     int vertex_index = 0;

     template <class T = int>
     struct dfs_visitor
     {};
   }

   BOOST_PARAMETER_NAME(graph)

   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)

   BOOST_PARAMETER_FUNCTION((void), f, tag,
     (required (graph, *))
   ''')

.. @example.append(') {}')
.. @test('compile')

If ``color_map`` were strictly going to be modified but not examined,
we could have written ``out(color_map)``.  There is no functional
difference between ``out`` and ``in_out``; the library provides
both so you can make your interfaces more self-documenting.

Positional Arguments
--------------------

When arguments are passed positionally (without the use of
keywords), they will be mapped onto parameters in the order the
parameters are given in the signature, so for example in this
call ::

  graphs::depth_first_search(x, y);

.. @ignore()

``x`` will always be interpreted as a graph and ``y`` will always
be interpreted as a visitor.

.. _sequence: http://boost-consulting.com/mplbook/preprocessor.html#sequences

Default Expression Evaluation
-----------------------------

.. compound::

  Note that in our example, the value of the graph parameter is
  used in the default expressions for ``root_vertex``,
  ``index_map`` and ``color_map``.  

  .. parsed-literal::

        (required (**graph**, \*) )
        (optional
          (visitor,           \*, boost::dfs_visitor<>()) 
          (root_vertex,       \*, \*vertices(**graph**).first) 
          (index_map,         \*, get(boost::vertex_index,\ **graph**)) 
          (in_out(color_map), \*, 
            default_color_map(num_vertices(**graph**), index_map) ) 
        )

  .. @ignore()

  A default expression is evaluated in the context of all preceding
  parameters, so you can use any of their values by name.

.. compound::

  A default expression is never evaluated—or even instantiated—if
  an actual argument is passed for that parameter.  We can actually
  demonstrate that with our code so far by replacing the body of
  ``depth_first_search`` with something that prints the arguments:

  .. parsed-literal::

    #include <boost/graph/depth_first_search.hpp> // for dfs_visitor

    BOOST_PARAMETER_FUNCTION(
        (void), depth_first_search, tag
        *…signature goes here…*
    )
    {
       std::cout << "graph=" << graph << std::endl;
       std::cout << "visitor=" << visitor << std::endl;
       std::cout << "root_vertex=" << root_vertex << std::endl;
       std::cout << "index_map=" << index_map << std::endl;
       std::cout << "color_map=" << color_map << std::endl;
    }

    int main()
    {
        depth_first_search(1, 2, 3, 4, 5);

        depth_first_search(
            "1", '2', _color_map = '5',
            _index_map = "4", _root_vertex = "3");
    }

  Despite the fact that default expressions such as
  ``vertices(graph).first`` are ill-formed for the given ``graph``
  arguments, both calls will compile, and each one will print
  exactly the same thing.

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>

   BOOST_PARAMETER_NAME(graph)
   BOOST_PARAMETER_NAME(visitor)
   BOOST_PARAMETER_NAME(root_vertex)
   BOOST_PARAMETER_NAME(index_map)
   BOOST_PARAMETER_NAME(color_map)''')

.. @example.replace_emphasis('''
   , (required 
       (graph, *)
       (visitor, *)
       (root_vertex, *)
       (index_map, *)
       (color_map, *)
     )
   ''')
.. @test('compile')

Signature Matching and Overloading
----------------------------------

In fact, the function signature is so general that any call to
``depth_first_search`` with fewer than five arguments will match
our function, provided we pass *something* for the required
``graph`` parameter.  That might not seem to be a problem at first;
after all, if the arguments don't match the requirements imposed by
the implementation of ``depth_first_search``, a compilation error
will occur later, when its body is instantiated.

There are at least three problems with very general function
signatures.  

1. By the time our ``depth_first_search`` is instantiated, it has
   been selected as the best matching overload.  Some other
   ``depth_first_search`` overload might've worked had it been
   chosen instead.  By the time we see a compilation error, there's
   no chance to change that decision.

2. Even if there are no overloads, error messages generated at
   instantiation time usually expose users to confusing
   implementation details.  For example, users might see references
   to names generated by ``BOOST_PARAMETER_FUNCTION`` such as
   ``graphs::detail::depth_first_search_with_named_params`` (or
   worse—think of the kinds of errors you get from your STL
   implementation when you make a mistake). [#ConceptCpp]_

3. The problems with exposing such permissive function template
   signatures have been the subject of much discussion, especially
   in the presence of `unqualified calls`__.  If all we want is to
   avoid unintentional argument-dependent lookup (ADL), we can
   isolate ``depth_first_search`` in a namespace containing no
   types [#using]_, but suppose we *want* it to found via ADL?

__ http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#225

It's usually a good idea to prevent functions from being considered
for overload resolution when the passed argument types aren't
appropriate.  The library already does this when the required
``graph`` parameter is not supplied, but we're not likely to see a
depth first search that doesn't take a graph to operate on.
Suppose, instead, that we found a different depth first search
algorithm that could work on graphs that don't model
|IncidenceGraph|_?  If we just added a simple overload,
it would be ambiguous::

  // new overload
  BOOST_PARAMETER_FUNCTION(
      (void), depth_first_search, (tag), (required (graph,*))( … ))
  {
      // new algorithm implementation
  }


  // ambiguous!
  depth_first_search(boost::adjacency_list<>(), 2, "hello");

.. @ignore()

Adding Type Requirements
........................

We really don't want the compiler to consider the original version
of ``depth_first_search`` because the ``root_vertex`` argument,
``"hello"``, doesn't meet the requirement__ that it match the
``graph`` parameter's vertex descriptor type.  Instead, this call
should just invoke our new overload.  To take the original
``depth_first_search`` overload out of contention, we need to tell
the library about this requirement by replacing the ``*`` element
of the signature with the required type, in parentheses:

__ `parameter table`_

.. parsed-literal::

  (root_vertex,       
       **(typename boost::graph_traits<graph_type>::vertex_descriptor)**,
       \*vertices(graph).first) 

.. @ignore()

Now the original ``depth_first_search`` will only be called when
the ``root_vertex`` argument can be converted to the graph's vertex
descriptor type, and our example that *was* ambiguous will smoothly
call the new overload.

.. Note:: The *type* of the ``graph`` argument is available in the
   signature—and in the function body—as ``graph_type``.  In
   general, to access the type of any parameter *foo*, write *foo*\
   ``_type``.


Predicate Requirements
......................

The requirements on other arguments are a bit more interesting than
those on ``root_vertex``; they can't be described in terms of simple
type matching.  Instead, they must be described in terms of `MPL
Metafunctions`__.  There's no space to give a complete description
of metafunctions or of graph library details here, but we'll show
you the complete signature with maximal checking, just to give you
a feel for how it's done.  Each predicate metafunction is enclosed
in parentheses *and preceded by an asterix*, as follows:

.. parsed-literal::

    BOOST_PARAMETER_FUNCTION(
        (void), depth_first_search, graphs

      , (required 
          (graph 
           , **\ \*(boost::mpl::and_<
                   boost::is_convertible<
                       boost::graph_traits<_>::traversal_category
                     , boost::incidence_graph_tag
                   >
                 , boost::is_convertible<
                       boost::graph_traits<_>::traversal_category
                     , boost::vertex_list_graph_tag
                   >
               >)** ))

        (optional
          (visitor, \*, boost::dfs_visitor<>()) // not checkable

          (root_vertex
            , (typename boost::graph_traits<graphs::graph::_>::vertex_descriptor)
            , \*vertices(graph).first)
 
          (index_map
            , **\ \*(boost::mpl::and_<
                  boost::is_integral<
                      boost::property_traits<_>::value_type
                  >
                , boost::is_same<
                      typename boost::graph_traits<graphs::graph::_>::vertex_descriptor
                    , boost::property_traits<_>::key_type
                  >
              >)**
            , get(boost::vertex_index,graph))
 
          (in_out(color_map)
            , **\ \*(boost::is_same<
                  typename boost::graph_traits<graphs::graph::_>::vertex_descriptor
                , boost::property_traits<_>::key_type
              >)**
           , default_color_map(num_vertices(graph), index_map) ) 
        )
    )

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME((_graph, graphs) graph) 
   BOOST_PARAMETER_NAME((_visitor, graphs) visitor) 
   BOOST_PARAMETER_NAME((_root_vertex, graphs) root_vertex) 
   BOOST_PARAMETER_NAME((_index_map, graphs) index_map) 
   BOOST_PARAMETER_NAME((_color_map, graphs) color_map)

   using boost::mpl::_;

   namespace boost
   {
     struct incidence_graph_tag {};
     struct vertex_list_graph_tag {};

     int vertex_index = 0;

     template <class T>
     struct graph_traits
     {
         typedef int traversal_category;
         typedef int vertex_descriptor;
     };

     template <class T>
     struct property_traits
     {
         typedef int value_type;
         typedef int key_type;
     };

     template <class T = int>
     struct dfs_visitor 
     {};
   }''')

.. @example.append('''
   {}''')

.. @test('compile')

__ ../../../mpl/doc/refmanual/metafunction.html

We acknowledge that this signature is pretty hairy looking.
Fortunately, it usually isn't necessary to so completely encode the
type requirements on arguments to generic functions.  However, it
is usally worth the effort to do so: your code will be more
self-documenting and will often provide a better user experience.
You'll also have an easier transition to an upcoming C++ standard
with `language support for concepts`__.

__ `ConceptC++`_

Deduced Parameters
------------------

To illustrate deduced parameter support we'll have to leave behind
our example from the Graph library.  Instead, consider the example
of the |def|_ function from Boost.Python_.  Its signature is
roughly as follows::

  template <
    class Function, Class KeywordExpression, class CallPolicies
  >
  void def(
      // Required parameters
      char const* name, Function func

      // Optional, deduced parameters
    , char const* docstring = ""
    , KeywordExpression keywords = no_keywords()
    , CallPolicies policies = default_call_policies()
  );

.. @ignore()

Try not to be too distracted by the use of the term “keywords” in
this example: although it means something analogous in Boost.Python
to what it means in the Parameter library, for the purposes of this
exercise you can think of it as being completely different.

When calling ``def``, only two arguments are required.  The
association between any additional arguments and their parameters
can be determined by the types of the arguments actually passed, so
the caller is neither required to remember argument positions or
explicitly specify parameter names for those arguments.  To
generate this interface using ``BOOST_PARAMETER_FUNCTION``, we need
only enclose the deduced parameters in a ``(deduced …)`` clause, as
follows: 

.. parsed-literal::

  namespace mpl = boost::mpl;

  BOOST_PARAMETER_FUNCTION(
      (void), def, tag,

      (required (name,(char const\*)) (func,\*) )   // nondeduced

      **(deduced** 
        (optional 
          (docstring, (char const\*), "")

          (keywords
             , \*(is_keyword_expression<mpl::_>) // see [#is_keyword_expression]_
             , no_keywords())

          (policies
             , \*(mpl::not_<
                   mpl::or_<
                       boost::is_convertible<mpl::_, char const\*>
                     , is_keyword_expression<mpl::_> // see [#is_keyword_expression]_
                   >
               >)
             , default_call_policies()
           )
         )
       **)**
   )
   {
      *…*
   }

.. @example.replace_emphasis('')

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(name)
   BOOST_PARAMETER_NAME(func)
   BOOST_PARAMETER_NAME(docstring)
   BOOST_PARAMETER_NAME(keywords)
   BOOST_PARAMETER_NAME(policies)

   struct default_call_policies
   {};

   struct no_keywords
   {};

   struct keywords
   {};

   template <class T>
   struct is_keyword_expression
     : boost::mpl::false_
   {};

   template <>
   struct is_keyword_expression<keywords>
     : boost::mpl::true_
   {};

   default_call_policies some_policies;

   void f()
   {}

   ''')

.. Admonition:: Syntax Note

  A ``(deduced …)`` clause always contains a ``(required …)``
  and/or an ``(optional …)`` subclause, and must follow any
  ``(required …)`` or ``(optional …)`` clauses indicating
  nondeduced parameters at the outer level.

With the declaration above, the following two calls are equivalent:

.. parsed-literal::

  def("f", &f, **some_policies**, **"Documentation for f"**);
  def("f", &f, **"Documentation for f"**, **some_policies**);

.. @example.prepend('''
   int main()
   {''')

If the user wants to pass a ``policies`` argument that was also,
for some reason, convertible to ``char const*``, she can always
specify the parameter name explicitly, as follows:

.. parsed-literal::

  def(
      "f", &f
     , **_policies = some_policies**, "Documentation for f");

.. @example.append('}')
.. @test('compile', howmany='all')

.. _Boost.Python: ../../../python/doc/index.html
.. |def| replace:: ``def``
.. _def: ../../../python/doc/v2/def.html

----------------------------------
Parameter-Enabled Member Functions
----------------------------------


The ``BOOST_PARAMETER_MEMBER_FUNCTION`` and
``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros accept exactly the
same arguments as ``BOOST_PARAMETER_FUNCTION``, but are designed to
be used within the body of a class::

  BOOST_PARAMETER_NAME(arg1)
  BOOST_PARAMETER_NAME(arg2)

  struct callable2
  {
      BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
          (void), operator(), tag, (required (arg1,(int))(arg2,(int))))
      {
          std::cout << arg1 << ", " << arg2 << std::endl;
      }
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

.. @test('compile')

These macros don't directly allow a function's interface to be
separated from its implementation, but you can always forward
arguments on to a separate implementation function::

  struct callable2
  {
      BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
          (void), operator(), tag, (required (arg1,(int))(arg2,(int))))
      {
          call_impl(arg1,arg2);
      }
   private:
      void call_impl(int, int); // implemented elsewhere.
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>

   BOOST_PARAMETER_NAME(arg1)
   BOOST_PARAMETER_NAME(arg2)''')

.. @test('compile')

------------------------------
Parameter-Enabled Constructors
------------------------------

The lack of a “delegating constructor”
feature in C++
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf)
limits somewhat the quality of interface this library can provide
for defining parameter-enabled constructors.  The usual workaround
for a lack of constructor delegation applies: one must factor the
common logic into a base class.  

Let's build a parameter-enabled constructor that simply prints its
arguments.  The first step is to write a base class whose
constructor accepts a single argument known as an |ArgumentPack|_:
a bundle of references to the actual arguments, tagged with their
keywords.  The values of the actual arguments are extracted from
the |ArgumentPack| by *indexing* it with keyword objects::

  BOOST_PARAMETER_NAME(name)
  BOOST_PARAMETER_NAME(index)

  struct myclass_impl
  {
      template <class ArgumentPack>
      myclass_impl(ArgumentPack const& args)
      {
          std::cout << "name = " << args[_name] 
                    << "; index = " << args[_index | 42] 
                    << std::endl;
      }
  };

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Note that the bitwise or (“\ ``|``\ ”) operator has a special
meaning when applied to keyword objects that are passed to an
|ArgumentPack|\ 's indexing operator: it is used to indicate a
default value.  In this case if there is no ``index`` parameter in
the |ArgumentPack|, ``42`` will be used instead.

Now we are ready to write the parameter-enabled constructor
interface::

  struct myclass : myclass_impl
  {
      BOOST_PARAMETER_CONSTRUCTOR(
          myclass, (myclass_impl), tag
        , (required (name,*)) (optional (index,*))) // no semicolon
  };

Since we have supplied a default value for ``index`` but not for
``name``, only ``name`` is required.  We can exercise our new
interface as follows::

  myclass x("bob", 3);                     // positional
  myclass y(_index = 12, _name = "sally"); // named
  myclass z("june");                       // positional/defaulted

.. @example.wrap('int main() {', '}')
.. @test('run', howmany='all')

For more on |ArgumentPack| manipulation, see the `Advanced Topics`_
section.

---------------------------------
Parameter-Enabled Class Templates
---------------------------------

In this section we'll use Boost.Parameter to build Boost.Python_\
's `class_`_ template, whose “signature” is:

.. parsed-literal::

  template class<
      ValueType, BaseList = bases<>
    , HeldType = ValueType, Copyable = void
  >
  class class\_;

.. @ignore()

Only the first argument, ``ValueType``, is required.

.. _class_: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec

Named Template Parameters
=========================

First, we'll build an interface that allows users to pass arguments
positionally or by name:

.. parsed-literal::

  struct B { virtual ~B() = 0; };
  struct D : B { ~D(); };

  class_<
       **class_type<B>**, **copyable<boost::noncopyable>** 
  > …;

  class_<
      **D**, **held_type<std::auto_ptr<D> >**, **base_list<bases<B> >**
  > …;

.. @ignore()

Template Keywords
-----------------

The first step is to define keywords for each template parameter::

  namespace boost { namespace python {

  BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @test('compile')

The declaration of the ``class_type`` keyword you see here is
equivalent to::

  namespace boost { namespace python {

  namespace tag { struct class_type; } // keyword tag type
  template <class T>
  struct class_type
    : parameter::template_keyword<tag::class_type,T>
  {};

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @test('compile')

It defines a keyword tag type named ``tag::class_type`` and a
*parameter passing template* named ``class_type``.

Class Template Skeleton
-----------------------

The next step is to define the skeleton of our class template,
which has three optional parameters.  Because the user may pass
arguments in any order, we don't know the actual identities of
these parameters, so it would be premature to use descriptive names
or write out the actual default values for any of them.  Instead,
we'll give them generic names and use the special type
``boost::parameter::void_`` as a default:

.. parsed-literal::

  namespace boost { namespace python {

  template <
      class A0
    , class A1 = parameter::void\_
    , class A2 = parameter::void\_
    , class A3 = parameter::void\_
  >
  struct class\_
  {
      *…*
  };

  }}

.. @example.prepend('#include <boost/parameter.hpp>')
.. @example.replace_emphasis('')
.. @test('compile')

Class Template Signatures
-------------------------

Next, we need to build a type, known as a |ParameterSpec|_,
describing the “signature” of ``boost::python::class_``.  A
|ParameterSpec|_ enumerates the required and optional parameters in
their positional order, along with any type requirements (note that
it does *not* specify defaults -- those will be dealt with
separately)::

  namespace boost { namespace python {

  using boost::mpl::_;

  typedef parameter::parameters<
      required<tag::class_type, is_class<_> >
    , optional<tag::base_list, mpl::is_sequence<_> >
    , optional<tag::held_type>
    , optional<tag::copyable>
  > class_signature;

  }}

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/mpl/is_sequence.hpp>
   #include <boost/noncopyable.hpp>
   #include <memory>

   using namespace boost::parameter;

   namespace boost { namespace python {

   BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

   template <class B = int>
   struct bases
   {};

   }}''')

.. |ParameterSpec| replace:: :concept:`ParameterSpec`

.. _ParameterSpec: reference.html#parameterspec

.. _binding_intro:

Argument Packs and Parameter Extraction
---------------------------------------

Next, within the body of ``class_`` , we use the |ParameterSpec|\
's nested ``::bind< … >`` template to bundle the actual arguments
into an |ArgumentPack|_ type, and then use the library's ``binding<
… >`` metafunction to extract “logical parameters”.  Note that
defaults are specified by supplying an optional third argument to
``binding< … >``::

  namespace boost { namespace python {

  template <
      class A0
    , class A1 = parameter::void_
    , class A2 = parameter::void_
    , class A3 = parameter::void_
  >
  struct class_
  {
      // Create ArgumentPack
      typedef typename 
        class_signature::bind<A0,A1,A2,A3>::type 
      args;

      // Extract first logical parameter.
      typedef typename parameter::binding<
        args, tag::class_type>::type class_type;
      
      typedef typename parameter::binding<
        args, tag::base_list, bases<> >::type base_list;
      
      typedef typename parameter::binding<
        args, tag::held_type, class_type>::type held_type;
      
      typedef typename parameter::binding<
        args, tag::copyable, void>::type copyable;
  };

  }}

.. |ArgumentPack| replace:: :concept:`ArgumentPack`
.. _ArgumentPack: reference.html#argumentpack

Exercising the Code So Far
==========================

.. compound::

  Revisiting our original examples, ::

    typedef boost::python::class_<
        class_type<B>, copyable<boost::noncopyable> 
    > c1;

    typedef boost::python::class_<
        D, held_type<std::auto_ptr<D> >, base_list<bases<B> > 
    > c2;

  .. @example.prepend('''
     using boost::python::class_type;
     using boost::python::copyable;
     using boost::python::held_type;
     using boost::python::base_list;
     using boost::python::bases;

     struct B {};
     struct D {};''')

  we can now examine the intended parameters::

    BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
    BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
    BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
    BOOST_MPL_ASSERT((
         boost::is_same<c1::copyable, boost::noncopyable>
    ));

    BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
    BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
    BOOST_MPL_ASSERT((
        boost::is_same<c2::held_type, std::auto_ptr<D> >
    ));
    BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));

.. @test('compile', howmany='all')

Deduced Template Parameters
===========================

To apply a deduced parameter interface here, we need only make the
type requirements a bit tighter so the ``held_type`` and
``copyable`` parameters can be crisply distinguished from the
others.  Boost.Python_ does this by requiring that ``base_list`` be
a specialization of its ``bases< … >`` template (as opposed to
being any old MPL sequence) and by requiring that ``copyable``, if
explicitly supplied, be ``boost::noncopyable``.  One easy way of
identifying specializations of ``bases< … >`` is to derive them all
from the same class, as an implementation detail:

.. parsed-literal::

  namespace boost { namespace python {

  namespace detail { struct bases_base {}; }

  template <class A0 = void, class A1 = void, class A2 = void *…* >
  struct bases **: detail::bases_base**
  {};

  }}  

.. @example.replace_emphasis('')
.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/mpl/is_sequence.hpp>
   #include <boost/noncopyable.hpp>
   #include <memory>

   using namespace boost::parameter;
   using boost::mpl::_;

   namespace boost { namespace python {

   BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
   BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)

   }}''')

Now we can rewrite our signature to make all three optional
parameters deducible::

  typedef parameter::parameters<
      required<tag::class_type, is_class<_> >

    , optional<
          deduced<tag::base_list>
        , is_base_and_derived<detail::bases_base,_>
      >

    , optional<
          deduced<tag::held_type>
        , mpl::not_<
              mpl::or_<
                  is_base_and_derived<detail::bases_base,_>
                , is_same<noncopyable,_>
              >
          >
      >

    , optional<deduced<tag::copyable>, is_same<noncopyable,_> >

  > class_signature;

.. @example.prepend('''
   namespace boost { namespace python {''')

.. @example.append('''
   template <
       class A0
     , class A1 = parameter::void_
     , class A2 = parameter::void_
     , class A3 = parameter::void_
   >
   struct class_
   {
       // Create ArgumentPack
       typedef typename 
         class_signature::bind<A0,A1,A2,A3>::type 
       args;
 
       // Extract first logical parameter.
       typedef typename parameter::binding<
         args, tag::class_type>::type class_type;
      
       typedef typename parameter::binding<
         args, tag::base_list, bases<> >::type base_list;
      
       typedef typename parameter::binding<
         args, tag::held_type, class_type>::type held_type;
      
       typedef typename parameter::binding<
         args, tag::copyable, void>::type copyable;
   };

   }}''')

It may seem like we've added a great deal of complexity, but the
benefits to our users are greater.  Our original examples can now
be written without explicit parameter names:

.. parsed-literal::

  typedef boost::python::class_<**B**, **boost::noncopyable**> c1;

  typedef boost::python::class_<**D**, **std::auto_ptr<D>**, **bases<B>** > c2;

.. @example.prepend('''
   struct B {};
   struct D {};

   using boost::python::bases;''')

.. @example.append('''
   BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
   BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
   BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
   BOOST_MPL_ASSERT((
        boost::is_same<c1::copyable, boost::noncopyable>
   ));

   BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
   BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
   BOOST_MPL_ASSERT((
       boost::is_same<c2::held_type, std::auto_ptr<D> >
   ));
   BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));''')

.. @test('compile', howmany='all')

===============
Advanced Topics
===============

At this point, you should have a good grasp of the basics.  In this
section we'll cover some more esoteric uses of the library.

-------------------------
Fine-Grained Name Control
-------------------------

If you don't like the leading-underscore naming convention used
to refer to keyword objects, or you need the name ``tag`` for
something other than the keyword type namespace, there's another
way to use ``BOOST_PARAMETER_NAME``:

.. parsed-literal::

   BOOST_PARAMETER_NAME(\ **(**\ *object-name*\ **,** *tag-namespace*\ **)** *parameter-name*\ )

.. @ignore()

Here is a usage example:

.. parsed-literal::

  BOOST_PARAMETER_NAME((**pass_foo**, **keywords**) **foo**)

  BOOST_PARAMETER_FUNCTION(
    (int), f, 
    **keywords**, (required (**foo**, \*)))
  {
      return **foo** + 1;
  }

  int x = f(**pass_foo** = 41);

.. @example.prepend('#include <boost/parameter.hpp>')
.. @example.append('''
   int main()
   {}''')
.. @test('run')

Before you use this more verbose form, however, please read the
section on `best practices for keyword object naming`__.

__ `Keyword Naming`_

-----------------------
More |ArgumentPack|\ s
-----------------------

We've already seen |ArgumentPack|\ s when we looked at
`parameter-enabled constructors`_ and `class templates`__.  As you
might have guessed, |ArgumentPack|\ s actually lie at the heart of
everything this library does; in this section we'll examine ways to
build and manipulate them more effectively.

__ binding_intro_

Building |ArgumentPack|\ s
==========================

The simplest |ArgumentPack| is the result of assigning into a
keyword object::

   BOOST_PARAMETER_NAME(index)

   template <class ArgumentPack>
   int print_index(ArgumentPack const& args)
   {
       std::cout << "index = " << args[_index] << std::endl;
       return 0;
   }

   int x = print_index(_index = 3);  // prints "index = 3"

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Also, |ArgumentPack|\ s can be composed using the comma operator.
The extra parentheses below are used to prevent the compiler from
seeing two separate arguments to ``print_name_and_index``::

   BOOST_PARAMETER_NAME(name)

   template <class ArgumentPack>
   int print_name_and_index(ArgumentPack const& args)
   {
       std::cout << "name = " << args[_name] << "; ";
       return print_index(args);
   }

   int y = print_name_and_index((_index = 3, _name = "jones"));

To build an |ArgumentPack| with positional arguments, we can use a
|ParameterSpec|_.  As introduced described in the section on `Class
Template Signatures`_, a |ParameterSpec| describes the positional
order of parameters and any associated type requirements.  Just as
we can build an |ArgumentPack| *type* with its nested ``::bind< …
>`` template, we can build an |ArgumentPack| *object* by invoking
its function call operator:

.. parsed-literal::

  parameter::parameters<
      required<tag::\ name, is_convertible<_,char const*> >
    , optional<tag::\ index, is_convertible<_,int> >
  > spec;

  char const sam[] = "sam";
  int twelve = 12;

  int z0 = print_name_and_index( **spec(**\ sam, twelve\ **)** );

  int z1 = print_name_and_index( 
     **spec(**\ _index=12, _name="sam"\ **)** 
  );

.. @example.prepend('''
   namespace parameter = boost::parameter;
   using parameter::required;
   using parameter::optional;
   using boost::is_convertible;
   using boost::mpl::_;''')

.. @example.append('''
   int main()
   {}''')

.. @test('run', howmany='all')

Note that because of the `forwarding problem`_, ``parameter::parameters::operator()``
can't accept non-const rvalues.

.. _`forwarding problem`: http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

Extracting Parameter Types
==========================

If we want to know the types of the arguments passed to
``print_name_and_index``, we have a couple of options.  The
simplest and least error-prone approach is to forward them to a
function template and allow *it* to do type deduction::

   BOOST_PARAMETER_NAME(name)
   BOOST_PARAMETER_NAME(index)

   template <class Name, class Index>
   int deduce_arg_types_impl(Name& name, Index& index)
   {
       Name& n2 = name;  // we know the types
       Index& i2 = index;
       return index;
   }

   template <class ArgumentPack>
   int deduce_arg_types(ArgumentPack const& args)
   {
       return deduce_arg_types_impl(args[_name], args[_index|42]);
   }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <cassert>''')

.. @example.append('''
   int a1 = deduce_arg_types((_name = "foo"));
   int a2 = deduce_arg_types((_name = "foo", _index = 3));

   int main()
   {
       assert(a1 == 42);
       assert(a2 == 3);
   }''')

.. @test('run')

Occasionally one needs to deduce argument types without an extra
layer of function call.  For example, suppose we wanted to return
twice the value of the ``index`` parameter?  In that
case we can use the ``binding< … >`` metafunction introduced
`earlier`__::

   BOOST_PARAMETER_NAME(index)

   template <class ArgumentPack>
   typename remove_reference<
       typename parameter::binding<ArgumentPack, tag::index, int>::type
   >::type
   twice_index(ArgumentPack const& args)
   {
       return 2 * args[_index|42];
   }

   int six = twice_index(_index = 3);

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <boost/type_traits/remove_reference.hpp>
   #include <cassert>

   namespace parameter = boost::parameter;
   using boost::remove_reference;''')

Note that the ``remove_reference< … >`` dance is necessary because
``binding< … >`` will return a reference type when the argument
is bound in the argument pack. If we don't strip the reference we
end up returning a reference to the temporary created in the ``2 * …``
expression. A convenient shortcut would be to use the ``value_type< … >``
metafunction:

.. parsed-literal::

   template <class ArgumentPack>
   typename **parameter::value_type<ArgumentPack, tag::index, int>**::type
   twice_index(ArgumentPack const& args)
   {
       return 2 * args[_index|42];
   }

.. @example.wrap('namespace with_value_type {', '''
   int six = twice_index(_index = 3);
   }''')

.. TODO: binding<> returns a reference. We should use value_type<> here.

.. @example.append('''
   int main()
   {
       assert(six == 6);
       assert(with_value_type::six == 6);
   }''')

.. @test('run', howmany='all')

__ binding_intro_

Lazy Default Computation
========================

When a default value is expensive to compute, it would be
preferable to avoid it until we're sure it's absolutely necessary.
``BOOST_PARAMETER_FUNCTION`` takes care of that problem for us, but
when using |ArgumentPack|\ s explicitly, we need a tool other than
``operator|``::

   BOOST_PARAMETER_NAME(s1)
   BOOST_PARAMETER_NAME(s2)
   BOOST_PARAMETER_NAME(s3)

   template <class ArgumentPack>
   std::string f(ArgumentPack const& args)
   {
       std::string const& s1 = args[_s1];
       std::string const& s2 = args[_s2];
       typename parameter::binding<
           ArgumentPack,tag::s3,std::string
       >::type s3 = args[_s3|(s1+s2)]; // always constructs s1+s2
       return s3;
   }

   std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <string>
   
   namespace parameter = boost::parameter;''')

.. @example.append('''
   int main()
   {}''')

.. @test('run')

In the example above, the string ``"hello, world"`` is constructed
despite the fact that the user passed us a value for ``s3``.  To
remedy that, we can compute the default value *lazily* (that is,
only on demand), by using ``boost::bind()`` to create a function
object.

.. danielw: I'm leaving the text below in the source, because we might
.. want to change back to it after 1.34, and if I remove it now we
.. might forget about it.

.. by combining the logical-or (“``||``”) operator
.. with a function object built by the Boost Lambda_ library: [#bind]_

.. parsed-literal::

   using boost::bind;
   using boost::ref;

   typename parameter::binding<
       ArgumentPack, tag::s3, std::string
   >::type s3 = args[_s3 **|| bind(std::plus<std::string>(), ref(s1), ref(s2))** ];

.. @example.prepend('''
   #include <boost/bind.hpp>
   #include <boost/ref.hpp>
   #include <boost/parameter.hpp>
   #include <string>
   #include <functional>

   namespace parameter = boost::parameter;

   BOOST_PARAMETER_NAME(s1)
   BOOST_PARAMETER_NAME(s2)
   BOOST_PARAMETER_NAME(s3)

   template <class ArgumentPack>
   std::string f(ArgumentPack const& args)
   {
       std::string const& s1 = args[_s1];
       std::string const& s2 = args[_s2];''')

.. @example.append('''
       return s3;
   }

   std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));

   int main()
   {}''')

.. @test('run')

.. .. _Lambda: ../../../lambda/index.html

.. sidebar:: Mnemonics

   To remember the difference between ``|`` and ``||``, recall that
   ``||`` normally uses short-circuit evaluation: its second
   argument is only evaluated if its first argument is ``false``.
   Similarly, in ``color_map[param||f]``, ``f`` is only invoked if
   no ``color_map`` argument was supplied.

The expression ``bind(std::plus<std::string>(), ref(s1), ref(s2))`` yields
a *function object* that, when invoked, adds the two strings together.
That function will only be invoked if no ``s3`` argument is supplied by 
the caller.

.. The expression ``lambda::var(s1)+lambda::var(s2)`` yields a
.. *function object* that, when invoked, adds the two strings
.. together.  That function will only be invoked if no ``s3`` argument
.. is supplied by the caller.

================ 
 Best Practices
================

By now you should have a fairly good idea of how to use the
Parameter library.  This section points out a few more-marginal
issues that will help you use the library more effectively.

--------------
Keyword Naming
--------------

``BOOST_PARAMETER_NAME`` prepends a leading underscore to the names
of all our keyword objects in order to avoid the following
usually-silent bug:

.. parsed-literal::

  namespace people
  {
    namespace tag { struct name; struct age;  }

    namespace // unnamed
    {
      boost::parameter::keyword<tag::name>& **name**
      = boost::parameter::keyword<tag::name>::instance;
      boost::parameter::keyword<tag::age>& **age**
      = boost::parameter::keyword<tag::age>::instance;
    }

    BOOST_PARAMETER_FUNCTION(
        (void), g, tag, (optional (name, \*, "bob")(age, \*, 42)))
    {
        std::cout << name << ":" << age;
    }

    void f(int age)
    {
    :vellipsis:`\ 
       .
       .
       .
     ` 
       g(**age** = 3); // whoops!
    }
  }

.. @ignore()

Although in the case above, the user was trying to pass the value
``3`` as the ``age`` parameter to ``g``, what happened instead
was that ``f``\ 's ``age`` argument got reassigned the value 3,
and was then passed as a positional argument to ``g``.  Since
``g``'s first positional parameter is ``name``, the default value
for ``age`` is used, and g prints ``3:42``.  Our leading
underscore naming convention that makes this problem less likely
to occur.

In this particular case, the problem could have been detected if
f's ``age`` parameter had been made ``const``, which is always a
good idea whenever possible.  Finally, we recommend that you use
an enclosing namespace for all your code, but particularly for
names with leading underscores.  If we were to leave out the
``people`` namespace above, names in the global namespace
beginning with leading underscores—which are reserved to your C++
compiler—might become irretrievably ambiguous with those in our
unnamed namespace.

----------
Namespaces
----------

In our examples we've always declared keyword objects in (an
unnamed namespace within) the same namespace as the
Boost.Parameter-enabled functions using those keywords:

.. parsed-literal::

  namespace lib
  {
    **BOOST_PARAMETER_NAME(name)
    BOOST_PARAMETER_NAME(index)**

    BOOST_PARAMETER_FUNCTION(
      (int), f, tag, 
      (optional (name,*,"bob")(index,(int),1))
    )
    {
        std::cout << name << ":" << index << std::endl;
        return index;
    }
  }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')
.. @namespace_setup = str(example)
.. @ignore()

Users of these functions have a few choices:

1. Full qualification:

  .. parsed-literal::

    int x = **lib::**\ f(**lib::**\ _name = "jill", **lib::**\ _index = 1);

  This approach is more verbose than many users would like.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

2. Make keyword objects available through
   *using-declarations*:

  .. parsed-literal::

    **using lib::_name;
    using lib::_index;**

    int x = lib::f(_name = "jill", _index = 1);

  This version is much better at the actual call site, but the
  *using-declarations* themselves can be verbose and hard-to
  manage.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

3. Bring in the entire namespace with a *using-directive*:

  .. parsed-literal::

    **using namespace lib;**
    int x = **f**\ (_name = "jill", _index = 3);

  This option is convenient, but it indiscriminately makes the
  *entire* contents of ``lib`` available without qualification.

.. @example.prepend(namespace_setup)
.. @example.append('int main() {}')
.. @test('run')

If we add an additional namespace around keyword declarations,
though, we can give users more control:

.. parsed-literal::

  namespace lib
  {
    **namespace keywords
    {**
       BOOST_PARAMETER_NAME(name)
       BOOST_PARAMETER_NAME(index)
    **}**

    BOOST_PARAMETER_FUNCTION(
      (int), f, **keywords::**\ tag, 
      (optional (name,*,"bob")(index,(int),1))
    )
    {
        std::cout << name << ":" << index << std::endl;
        return index;
    }
  }

.. @example.prepend('''
   #include <boost/parameter.hpp>
   #include <iostream>''')

Now users need only a single *using-directive* to bring in just the
names of all keywords associated with ``lib``:

.. parsed-literal::
  
  **using namespace lib::keywords;**
  int y = lib::f(_name = "bob", _index = 2);

.. @example.append('int main() {}')
.. @test('run', howmany='all')

-------------
Documentation
-------------

The interface idioms enabled by Boost.Parameter are completely new
(to C++), and as such are not served by pre-existing documentation
conventions.  

.. Note:: This space is empty because we haven't settled on any
   best practices yet.  We'd be very pleased to link to your
   documentation if you've got a style that you think is worth
   sharing.

============================
 Portability Considerations
============================

Use the `regression test results`_ for the latest Boost release of
the Parameter library to see how it fares on your favorite
compiler.  Additionally, you may need to be aware of the following
issues and workarounds for particular compilers.

.. _`regression test results`: http://www.boost.org/regression/release/user/parameter.html

-----------------
No SFINAE Support
-----------------

Some older compilers don't support SFINAE.  If your compiler meets
that criterion, then Boost headers will ``#define`` the preprocessor
symbol ``BOOST_NO_SFINAE``, and parameter-enabled functions won't be
removed from the overload set based on their signatures.

---------------------------
No Support for |result_of|_
---------------------------

.. |result_of| replace:: ``result_of``

.. _result_of: ../../../utility/utility.htm#result_of

`Lazy default computation`_ relies on the |result_of| class
template to compute the types of default arguments given the type
of the function object that constructs them.  On compilers that
don't support |result_of|, ``BOOST_NO_RESULT_OF`` will be
``#define``\ d, and the compiler will expect the function object to
contain a nested type name, ``result_type``, that indicates its
return type when invoked without arguments.  To use an ordinary
function as a default generator on those compilers, you'll need to
wrap it in a class that provides ``result_type`` as a ``typedef``
and invokes the function via its ``operator()``.

.. 
  Can't Declare |ParameterSpec| via ``typedef``
  =============================================

  In principle you can declare a |ParameterSpec| as a ``typedef``
  for a specialization of ``parameters<…>``, but Microsoft Visual C++
  6.x has been seen to choke on that usage.  The workaround is to use
  inheritance and declare your |ParameterSpec| as a class:

  .. parsed-literal::

       **struct dfs_parameters
         :** parameter::parameters<
             tag::graph, tag::visitor, tag::root_vertex
           , tag::index_map, tag::color_map
       > **{};**


  Default Arguments Unsupported on Nested Templates
  =================================================

  As of this writing, Borland compilers don't support the use of
  default template arguments on member class templates.  As a result,
  you have to supply ``BOOST_PARAMETER_MAX_ARITY`` arguments to every
  use of ``parameters<…>::match``.  Since the actual defaults used
  are unspecified, the workaround is to use
  |BOOST_PARAMETER_MATCH|_ to declare default arguments for SFINAE.

  .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH``

--------------------------------------------------
Compiler Can't See References In Unnamed Namespace
--------------------------------------------------

If you use Microsoft Visual C++ 6.x, you may find that the compiler
has trouble finding your keyword objects.  This problem has been
observed, but only on this one compiler, and it disappeared as the
test code evolved, so we suggest you use it only as a last resort
rather than as a preventative measure.  The solution is to add
*using-declarations* to force the names to be available in the
enclosing namespace without qualification::

    namespace graphs
    {
      using graphs::graph;
      using graphs::visitor;
      using graphs::root_vertex;
      using graphs::index_map;
      using graphs::color_map;
    }

================
 Python Binding
================

.. _python: python.html

Follow `this link`__ for documentation on how to expose
Boost.Parameter-enabled functions to Python with `Boost.Python`_.

__ python.html

===========
 Reference
===========

.. _reference: reference.html

Follow `this link`__ to the Boost.Parameter reference
documentation.  

__ reference.html

==========
 Glossary
==========

.. _arguments:

:Argument (or “actual argument”): the value actually passed to a
  function or class template

.. _parameter:

:Parameter (or “formal parameter”): the name used to refer to an
  argument within a function or class template.  For example, the
  value of ``f``'s *parameter* ``x`` is given by the *argument*
  ``3``::

    int f(int x) { return x + 1 }
    int y = f(3);

==================
 Acknowledgements
==================

The authors would like to thank all the Boosters who participated
in the review of this library and its documentation, most
especially our review manager, Doug Gregor.

--------------------------

.. [#old_interface] As of Boost 1.33.0 the Graph library was still
   using an `older named parameter mechanism`__, but there are
   plans to change it to use Boost.Parameter (this library) in an
   upcoming release, while keeping the old interface available for
   backward-compatibility.  

__ ../../../graph/doc/bgl_named_params.html

.. [#odr] The **One Definition Rule** says that any given entity in
   a C++ program must have the same definition in all translation
   units (object files) that make up a program.

.. [#vertex_descriptor] If you're not familiar with the Boost Graph
   Library, don't worry about the meaning of any
   Graph-library-specific details you encounter.  In this case you
   could replace all mentions of vertex descriptor types with
   ``int`` in the text, and your understanding of the Parameter
   library wouldn't suffer.

.. [#ConceptCpp] This is a major motivation behind `ConceptC++`_.

.. _`ConceptC++`: http://www.generic-programming.org/software/ConceptGCC/

.. .. [#bind] The Lambda library is known not to work on `some
..   less-conformant compilers`__.  When using one of those you could
..   use `Boost.Bind`_ to generate the function object::

..      boost::bind(std::plus<std::string>(),s1,s2)

.. [#is_keyword_expression] Here we're assuming there's a predicate
   metafunction ``is_keyword_expression`` that can be used to
   identify models of Boost.Python's KeywordExpression concept.

.. .. __ http://www.boost.org/regression/release/user/lambda.html
.. _Boost.Bind: ../../../bind/index.html


.. [#using] You can always give the illusion that the function
   lives in an outer namespace by applying a *using-declaration*::

      namespace foo_overloads
      {
        // foo declarations here
        void foo() { ... }
        ...
      }
      using foo_overloads::foo;

    This technique for avoiding unintentional argument-dependent
    lookup is due to Herb Sutter.


.. [#sfinae] This capability depends on your compiler's support for SFINAE. 
   **SFINAE**: **S**\ ubstitution **F**\ ailure **I**\ s
   **N**\ ot **A**\ n **E** rror.  If type substitution during the
   instantiation of a function template results in an invalid type,
   no compilation error is emitted; instead the overload is removed
   from the overload set. By producing an invalid type in the
   function signature depending on the result of some condition,
   we can decide whether or not an overload is considered during overload
   resolution.  The technique is formalized in
   the |enable_if|_ utility.  Most recent compilers support SFINAE;
   on compilers that don't support it, the Boost config library
   will ``#define`` the symbol ``BOOST_NO_SFINAE``.
   See
   http://www.semantics.org/once_weakly/w02_SFINAE.pdf for more
   information on SFINAE.

.. |enable_if| replace:: ``enable_if``
.. _enable_if: ../../../utility/enable_if.html