2017-06-07 00:02:25 +03:00
<!DOCTYPE html>
< html lang = "en" >
2017-03-14 22:57:07 +02:00
< head >
2017-06-07 00:02:25 +03:00
< meta charset = "UTF-8" >
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
2017-07-17 19:28:36 +03:00
< meta name = "generator" content = "Asciidoctor 1.5.6" >
2017-06-07 00:02:25 +03:00
< meta name = "author" content = "Peter Dimov" >
2017-06-10 03:44:31 +03:00
< title > Boost.Mp11: A C++11 metaprogramming library</ title >
2017-06-07 00:02:25 +03:00
< link rel = "stylesheet" href = "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700" >
< style >
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article , aside , details , figcaption , figure , footer , header , hgroup , main , nav , section , summary { display : block }
audio , canvas , video { display : inline-block }
audio : not ([ controls ]) { display : none ; height : 0 }
[ hidden ], template { display : none }
script { display : none !important }
html { font-family : sans-serif ; -ms- text-size-adjust : 100 % ; -webkit- text-size-adjust : 100 % }
a { background : transparent }
a : focus { outline : thin dotted }
a : active , a : hover { outline : 0 }
h1 { font-size : 2 em ; margin : .67 em 0 }
abbr [ title ] { border-bottom : 1 px dotted }
b , strong { font-weight : bold }
dfn { font-style : italic }
hr { -moz- box-sizing : content-box ; box-sizing : content-box ; height : 0 }
mark { background : #ff0 ; color : #000 }
code , kbd , pre , samp { font-family : monospace ; font-size : 1 em }
pre { white-space : pre-wrap }
q { quotes : "\201C" "\201D" "\2018" "\2019" }
small { font-size : 80 % }
sub , sup { font-size : 75 % ; line-height : 0 ; position : relative ; vertical-align : baseline }
sup { top : -.5 em }
sub { bottom : -.25 em }
img { border : 0 }
svg : not ( : root ) { overflow : hidden }
figure { margin : 0 }
fieldset { border : 1 px solid silver ; margin : 0 2 px ; padding : .35 em .625 em .75 em }
legend { border : 0 ; padding : 0 }
button , input , select , textarea { font-family : inherit ; font-size : 100 % ; margin : 0 }
button , input { line-height : normal }
button , select { text-transform : none }
button , html input [ type = "button" ], input [ type = "reset" ], input [ type = "submit" ] { -webkit- appearance : button ; cursor : pointer }
button [ disabled ], html input [ disabled ] { cursor : default }
input [ type = "checkbox" ], input [ type = "radio" ] { box-sizing : border-box ; padding : 0 }
input [ type = "search" ] { -webkit- appearance : textfield ; -moz- box-sizing : content-box ; -webkit- box-sizing : content-box ; box-sizing : content-box }
input [ type = "search" ] :: -webkit-search-cancel-button , input [ type = "search" ] :: -webkit-search-decoration { -webkit- appearance : none }
button :: -moz-focus-inner , input :: -moz-focus-inner { border : 0 ; padding : 0 }
textarea { overflow : auto ; vertical-align : top }
table { border-collapse : collapse ; border-spacing : 0 }
*,* : before ,* : after { -moz- box-sizing : border-box ; -webkit- box-sizing : border-box ; box-sizing : border-box }
html , body { font-size : 100 % }
body { background : #fff ; color : rgba ( 0 , 0 , 0 , .8 ); padding : 0 ; margin : 0 ; font-family : "Noto Serif" , "DejaVu Serif" , serif ; font-weight : 400 ; font-style : normal ; line-height : 1 ; position : relative ; cursor : auto ; tab-size : 4 ; -moz- osx-font-smoothing : grayscale ; -webkit- font-smoothing : antialiased }
a : hover { cursor : pointer }
img , object , embed { max-width : 100 % ; height : auto }
object , embed { height : 100 % }
img { -ms- interpolation-mode : bicubic }
. left { float : left !important }
. right { float : right !important }
. text-left { text-align : left !important }
. text-right { text-align : right !important }
. text-center { text-align : center !important }
. text-justify { text-align : justify !important }
. hide { display : none }
img , object , svg { display : inline-block ; vertical-align : middle }
textarea { height : auto ; min-height : 50 px }
select { width : 100 % }
. center { margin-left : auto ; margin-right : auto }
. spread { width : 100 % }
p . lead , . paragraph . lead > p , # preamble > . sectionbody > . paragraph : first-of-type p { font-size : 1.21875 em ; line-height : 1.6 }
. subheader , . admonitionblock td . content > . title , . audioblock > . title , . exampleblock > . title , . imageblock > . title , . listingblock > . title , . literalblock > . title , . stemblock > . title , . openblock > . title , . paragraph > . title , . quoteblock > . title , table . tableblock > . title , . verseblock > . title , . videoblock > . title , . dlist > . title , . olist > . title , . ulist > . title , . qlist > . title , . hdlist > . title { line-height : 1.45 ; color : #7a2518 ; font-weight : 400 ; margin-top : 0 ; margin-bottom : .25 em }
div , dl , dt , dd , ul , ol , li , h1 , h2 , h3 , # toctitle , . sidebarblock > . content > . title , h4 , h5 , h6 , pre , form , p , blockquote , th , td { margin : 0 ; padding : 0 ; direction : ltr }
a { color : #2156a5 ; text-decoration : underline ; line-height : inherit }
a : hover , a : focus { color : #1d4b8f }
a img { border : none }
p { font-family : inherit ; font-weight : 400 ; font-size : 1 em ; line-height : 1.6 ; margin-bottom : 1.25 em ; text-rendering : optimizeLegibility }
p aside { font-size : .875 em ; line-height : 1.35 ; font-style : italic }
h1 , h2 , h3 , # toctitle , . sidebarblock > . content > . title , h4 , h5 , h6 { font-family : "Open Sans" , "DejaVu Sans" , sans-serif ; font-weight : 300 ; font-style : normal ; color : #ba3925 ; text-rendering : optimizeLegibility ; margin-top : 1 em ; margin-bottom : .5 em ; line-height : 1.0125 em }
h1 small , h2 small , h3 small , # toctitle small , . sidebarblock > . content > . title small , h4 small , h5 small , h6 small { font-size : 60 % ; color : #e99b8f ; line-height : 0 }
h1 { font-size : 2.125 em }
h2 { font-size : 1.6875 em }
h3 , # toctitle , . sidebarblock > . content > . title { font-size : 1.375 em }
h4 , h5 { font-size : 1.125 em }
h6 { font-size : 1 em }
hr { border : solid #ddddd8 ; border-width : 1 px 0 0 ; clear : both ; margin : 1.25 em 0 1.1875 em ; height : 0 }
em , i { font-style : italic ; line-height : inherit }
strong , b { font-weight : bold ; line-height : inherit }
small { font-size : 60 % ; line-height : inherit }
code { font-family : "Droid Sans Mono" , "DejaVu Sans Mono" , monospace ; font-weight : 400 ; color : rgba ( 0 , 0 , 0 , .9 )}
ul , ol , dl { font-size : 1 em ; line-height : 1.6 ; margin-bottom : 1.25 em ; list-style-position : outside ; font-family : inherit }
2017-07-17 19:28:36 +03:00
ul , ol { margin-left : 1.5 em }
2017-06-07 00:02:25 +03:00
ul li ul , ul li ol { margin-left : 1.25 em ; margin-bottom : 0 ; font-size : 1 em }
ul . square li ul , ul . circle li ul , ul . disc li ul { list-style : inherit }
ul . square { list-style-type : square }
ul . circle { list-style-type : circle }
ul . disc { list-style-type : disc }
ol li ul , ol li ol { margin-left : 1.25 em ; margin-bottom : 0 }
dl dt { margin-bottom : .3125 em ; font-weight : bold }
dl dd { margin-bottom : 1.25 em }
abbr , acronym { text-transform : uppercase ; font-size : 90 % ; color : rgba ( 0 , 0 , 0 , .8 ); border-bottom : 1 px dotted #ddd ; cursor : help }
abbr { text-transform : none }
blockquote { margin : 0 0 1.25 em ; padding : .5625 em 1.25 em 0 1.1875 em ; border-left : 1 px solid #ddd }
blockquote cite { display : block ; font-size : .9375 em ; color : rgba ( 0 , 0 , 0 , .6 )}
blockquote cite : before { content : "\2014 \0020" }
blockquote cite a , blockquote cite a : visited { color : rgba ( 0 , 0 , 0 , .6 )}
blockquote , blockquote p { line-height : 1.6 ; color : rgba ( 0 , 0 , 0 , .85 )}
@ media only screen and ( min-width : 768px ) { h1 , h2 , h3 , # toctitle , . sidebarblock > . content > . title , h4 , h5 , h6 { line-height : 1.2 }
h1 { font-size : 2.75 em }
h2 { font-size : 2.3125 em }
h3 , # toctitle , . sidebarblock > . content > . title { font-size : 1.6875 em }
h4 { font-size : 1.4375 em }}
table { background : #fff ; margin-bottom : 1.25 em ; border : solid 1 px #dedede }
table thead , table tfoot { background : #f7f8f7 ; font-weight : bold }
table thead tr th , table thead tr td , table tfoot tr th , table tfoot tr td { padding : .5 em .625 em .625 em ; font-size : inherit ; color : rgba ( 0 , 0 , 0 , .8 ); text-align : left }
table tr th , table tr td { padding : .5625 em .625 em ; font-size : inherit ; color : rgba ( 0 , 0 , 0 , .8 )}
table tr . even , table tr . alt , table tr : nth-of-type ( even ) { background : #f8f8f7 }
table thead tr th , table tfoot tr th , table tbody tr td , table tr td , table tfoot tr td { display : table-cell ; line-height : 1.6 }
h1 , h2 , h3 , # toctitle , . sidebarblock > . content > . title , h4 , h5 , h6 { line-height : 1.2 ; word-spacing : -.05 em }
h1 strong , h2 strong , h3 strong , # toctitle strong , . sidebarblock > . content > . title strong , h4 strong , h5 strong , h6 strong { font-weight : 400 }
. clearfix : before , . clearfix : after , . float-group : before , . float-group : after { content : " " ; display : table }
. clearfix : after , . float-group : after { clear : both }
* : not ( pre )> code { font-size : .9375 em ; font-style : normal !important ; letter-spacing : 0 ; padding : .1 em .5 ex ; word-spacing : -.15 em ; background-color : #f7f7f8 ; -webkit- border-radius : 4 px ; border-radius : 4 px ; line-height : 1.45 ; text-rendering : optimizeSpeed ; word-wrap : break-word }
* : not ( pre )> code . nobreak { word-wrap : normal }
* : not ( pre )> code . nowrap { white-space : nowrap }
pre , pre > code { line-height : 1.45 ; color : rgba ( 0 , 0 , 0 , .9 ); font-family : "Droid Sans Mono" , "DejaVu Sans Mono" , monospace ; font-weight : 400 ; text-rendering : optimizeSpeed }
em em { font-style : normal }
strong strong { font-weight : 400 }
. keyseq { color : rgba ( 51 , 51 , 51 , .8 )}
kbd { font-family : "Droid Sans Mono" , "DejaVu Sans Mono" , monospace ; display : inline-block ; color : rgba ( 0 , 0 , 0 , .8 ); font-size : .65 em ; line-height : 1.45 ; background-color : #f7f7f7 ; border : 1 px solid #ccc ; -webkit- border-radius : 3 px ; border-radius : 3 px ; -webkit- box-shadow : 0 1 px 0 rgba ( 0 , 0 , 0 , .2 ), 0 0 0 .1 em white inset ; box-shadow : 0 1 px 0 rgba ( 0 , 0 , 0 , .2 ), 0 0 0 .1 em #fff inset ; margin : 0 .15 em ; padding : .2 em .5 em ; vertical-align : middle ; position : relative ; top : -.1 em ; white-space : nowrap }
. keyseq kbd : first-child { margin-left : 0 }
. keyseq kbd : last-child { margin-right : 0 }
2017-07-17 19:28:36 +03:00
. menuseq , . menuref { color : #000 }
. menuseq b : not ( . caret ), . menuref { font-weight : inherit }
. menuseq { word-spacing : -.02 em }
. menuseq b . caret { font-size : 1.25 em ; line-height : .8 }
. menuseq i . caret { font-weight : bold ; text-align : center ; width : .45 em }
2017-06-07 00:02:25 +03:00
b . button : before , b . button : after { position : relative ; top : -1 px ; font-weight : 400 }
b . button : before { content : "[" ; padding : 0 3 px 0 2 px }
b . button : after { content : "]" ; padding : 0 2 px 0 3 px }
p a > code : hover { color : rgba ( 0 , 0 , 0 , .9 )}
# header , # content , # footnotes , # footer { width : 100 % ; margin-left : auto ; margin-right : auto ; margin-top : 0 ; margin-bottom : 0 ; max-width : 62.5 em ; * zoom : 1 ; position : relative ; padding-left : .9375 em ; padding-right : .9375 em }
# header : before , # header : after , # content : before , # content : after , # footnotes : before , # footnotes : after , # footer : before , # footer : after { content : " " ; display : table }
# header : after , # content : after , # footnotes : after , # footer : after { clear : both }
# content { margin-top : 1.25 em }
# content : before { content : none }
# header > h1 : first-child { color : rgba ( 0 , 0 , 0 , .85 ); margin-top : 2.25 rem ; margin-bottom : 0 }
# header > h1 : first-child + # toc { margin-top : 8 px ; border-top : 1 px solid #ddddd8 }
# header > h1 : only-child , body . toc2 # header > h1 : nth-last-child ( 2 ) { border-bottom : 1 px solid #ddddd8 ; padding-bottom : 8 px }
# header . details { border-bottom : 1 px solid #ddddd8 ; line-height : 1.45 ; padding-top : .25 em ; padding-bottom : .25 em ; padding-left : .25 em ; color : rgba ( 0 , 0 , 0 , .6 ); display : -ms- flexbox ; display : -webkit- flex ; display : flex ; -ms- flex-flow : row wrap ; -webkit- flex-flow : row wrap ; flex-flow : row wrap }
# header . details span : first-child { margin-left : -.125 em }
# header . details span . email a { color : rgba ( 0 , 0 , 0 , .85 )}
# header . details br { display : none }
# header . details br + span : before { content : "\00a0\2013\00a0" }
# header . details br + span . author : before { content : "\00a0\22c5\00a0" ; color : rgba ( 0 , 0 , 0 , .85 )}
# header . details br + span # revremark : before { content : "\00a0|\00a0" }
# header # revnumber { text-transform : capitalize }
# header # revnumber : after { content : "\00a0" }
# content > h1 : first-child : not ([ class ]) { color : rgba ( 0 , 0 , 0 , .85 ); border-bottom : 1 px solid #ddddd8 ; padding-bottom : 8 px ; margin-top : 0 ; padding-top : 1 rem ; margin-bottom : 1.25 rem }
# toc { border-bottom : 1 px solid #efefed ; padding-bottom : .5 em }
# toc > ul { margin-left : .125 em }
# toc ul . sectlevel0 > li > a { font-style : italic }
# toc ul . sectlevel0 ul . sectlevel1 { margin : .5 em 0 }
# toc ul { font-family : "Open Sans" , "DejaVu Sans" , sans-serif ; list-style-type : none }
# toc li { line-height : 1.3334 ; margin-top : .3334 em }
# toc a { text-decoration : none }
# toc a : active { text-decoration : underline }
# toctitle { color : #7a2518 ; font-size : 1.2 em }
@ media only screen and ( min-width : 768px ) {# toctitle { font-size : 1.375 em }
body . toc2 { padding-left : 15 em ; padding-right : 0 }
# toc . toc2 { margin-top : 0 !important ; background-color : #f8f8f7 ; position : fixed ; width : 15 em ; left : 0 ; top : 0 ; border-right : 1 px solid #efefed ; border-top-width : 0 !important ; border-bottom-width : 0 !important ; z-index : 1000 ; padding : 1.25 em 1 em ; height : 100 % ; overflow : auto }
# toc . toc2 # toctitle { margin-top : 0 ; margin-bottom : .8 rem ; font-size : 1.2 em }
# toc . toc2 > ul { font-size : .9 em ; margin-bottom : 0 }
# toc . toc2 ul ul { margin-left : 0 ; padding-left : 1 em }
# toc . toc2 ul . sectlevel0 ul . sectlevel1 { padding-left : 0 ; margin-top : .5 em ; margin-bottom : .5 em }
body . toc2 . toc-right { padding-left : 0 ; padding-right : 15 em }
body . toc2 . toc-right # toc . toc2 { border-right-width : 0 ; border-left : 1 px solid #efefed ; left : auto ; right : 0 }}
@ media only screen and ( min-width : 1280px ) { body . toc2 { padding-left : 20 em ; padding-right : 0 }
# toc . toc2 { width : 20 em }
# toc . toc2 # toctitle { font-size : 1.375 em }
# toc . toc2 > ul { font-size : .95 em }
# toc . toc2 ul ul { padding-left : 1.25 em }
body . toc2 . toc-right { padding-left : 0 ; padding-right : 20 em }}
# content # toc { border-style : solid ; border-width : 1 px ; border-color : #e0e0dc ; margin-bottom : 1.25 em ; padding : 1.25 em ; background : #f8f8f7 ; -webkit- border-radius : 4 px ; border-radius : 4 px }
# content # toc > : first-child { margin-top : 0 }
# content # toc > : last-child { margin-bottom : 0 }
# footer { max-width : 100 % ; background-color : rgba ( 0 , 0 , 0 , .8 ); padding : 1.25 em }
# footer-text { color : rgba ( 255 , 255 , 255 , .8 ); line-height : 1.44 }
. sect1 { padding-bottom : .625 em }
@ media only screen and ( min-width : 768px ) {. sect1 { padding-bottom : 1.25 em }}
. sect1 + . sect1 { border-top : 1 px solid #efefed }
# content h1 > a . anchor , h2 > a . anchor , h3 > a . anchor , # toctitle > a . anchor , . sidebarblock > . content > . title > a . anchor , h4 > a . anchor , h5 > a . anchor , h6 > a . anchor { position : absolute ; z-index : 1001 ; width : 1.5 ex ; margin-left : -1.5 ex ; display : block ; text-decoration : none !important ; visibility : hidden ; text-align : center ; font-weight : 400 }
# content h1 > a . anchor : before , h2 > a . anchor : before , h3 > a . anchor : before , # toctitle > a . anchor : before , . sidebarblock > . content > . title > a . anchor : before , h4 > a . anchor : before , h5 > a . anchor : before , h6 > a . anchor : before { content : "\00A7" ; font-size : .85 em ; display : block ; padding-top : .1 em }
# content h1 : hover > a . anchor , # content h1 > a . anchor : hover , h2 : hover > a . anchor , h2 > a . anchor : hover , h3 : hover > a . anchor , # toctitle : hover > a . anchor , . sidebarblock > . content > . title : hover > a . anchor , h3 > a . anchor : hover , # toctitle > a . anchor : hover , . sidebarblock > . content > . title > a . anchor : hover , h4 : hover > a . anchor , h4 > a . anchor : hover , h5 : hover > a . anchor , h5 > a . anchor : hover , h6 : hover > a . anchor , h6 > a . anchor : hover { visibility : visible }
# content h1 > a . link , h2 > a . link , h3 > a . link , # toctitle > a . link , . sidebarblock > . content > . title > a . link , h4 > a . link , h5 > a . link , h6 > a . link { color : #ba3925 ; text-decoration : none }
# content h1 > a . link : hover , h2 > a . link : hover , h3 > a . link : hover , # toctitle > a . link : hover , . sidebarblock > . content > . title > a . link : hover , h4 > a . link : hover , h5 > a . link : hover , h6 > a . link : hover { color : #a53221 }
. audioblock , . imageblock , . literalblock , . listingblock , . stemblock , . videoblock { margin-bottom : 1.25 em }
. admonitionblock td . content > . title , . audioblock > . title , . exampleblock > . title , . imageblock > . title , . listingblock > . title , . literalblock > . title , . stemblock > . title , . openblock > . title , . paragraph > . title , . quoteblock > . title , table . tableblock > . title , . verseblock > . title , . videoblock > . title , . dlist > . title , . olist > . title , . ulist > . title , . qlist > . title , . hdlist > . title { text-rendering : optimizeLegibility ; text-align : left ; font-family : "Noto Serif" , "DejaVu Serif" , serif ; font-size : 1 rem ; font-style : italic }
table . tableblock > caption . title { white-space : nowrap ; overflow : visible ; max-width : 0 }
. paragraph . lead > p , # preamble > . sectionbody > . paragraph : first-of-type p { color : rgba ( 0 , 0 , 0 , .85 )}
table . tableblock # preamble > . sectionbody > . paragraph : first-of-type p { font-size : inherit }
. admonitionblock > table { border-collapse : separate ; border : 0 ; background : none ; width : 100 % }
. admonitionblock > table td . icon { text-align : center ; width : 80 px }
2017-07-17 19:28:36 +03:00
. admonitionblock > table td . icon img { max-width : initial }
2017-06-07 00:02:25 +03:00
. admonitionblock > table td . icon . title { font-weight : bold ; font-family : "Open Sans" , "DejaVu Sans" , sans-serif ; text-transform : uppercase }
. admonitionblock > table td . content { padding-left : 1.125 em ; padding-right : 1.25 em ; border-left : 1 px solid #ddddd8 ; color : rgba ( 0 , 0 , 0 , .6 )}
. admonitionblock > table td . content > : last-child > : last-child { margin-bottom : 0 }
. exampleblock > . content { border-style : solid ; border-width : 1 px ; border-color : #e6e6e6 ; margin-bottom : 1.25 em ; padding : 1.25 em ; background : #fff ; -webkit- border-radius : 4 px ; border-radius : 4 px }
. exampleblock > . content > : first-child { margin-top : 0 }
. exampleblock > . content > : last-child { margin-bottom : 0 }
. sidebarblock { border-style : solid ; border-width : 1 px ; border-color : #e0e0dc ; margin-bottom : 1.25 em ; padding : 1.25 em ; background : #f8f8f7 ; -webkit- border-radius : 4 px ; border-radius : 4 px }
. sidebarblock > : first-child { margin-top : 0 }
. sidebarblock > : last-child { margin-bottom : 0 }
. sidebarblock > . content > . title { color : #7a2518 ; margin-top : 0 ; text-align : center }
. exampleblock > . content > : last-child > : last-child , . exampleblock > . content . olist > ol > li : last-child > : last-child , . exampleblock > . content . ulist > ul > li : last-child > : last-child , . exampleblock > . content . qlist > ol > li : last-child > : last-child , . sidebarblock > . content > : last-child > : last-child , . sidebarblock > . content . olist > ol > li : last-child > : last-child , . sidebarblock > . content . ulist > ul > li : last-child > : last-child , . sidebarblock > . content . qlist > ol > li : last-child > : last-child { margin-bottom : 0 }
. literalblock pre , . listingblock pre : not ( . highlight ), . listingblock pre [ class = "highlight" ], . listingblock pre [ class ^= "highlight " ], . listingblock pre . CodeRay , . listingblock pre . prettyprint { background : #f7f7f8 }
. sidebarblock . literalblock pre , . sidebarblock . listingblock pre : not ( . highlight ), . sidebarblock . listingblock pre [ class = "highlight" ], . sidebarblock . listingblock pre [ class ^= "highlight " ], . sidebarblock . listingblock pre . CodeRay , . sidebarblock . listingblock pre . prettyprint { background : #f2f1f1 }
. literalblock pre , . literalblock pre [ class ], . listingblock pre , . listingblock pre [ class ] { -webkit- border-radius : 4 px ; border-radius : 4 px ; word-wrap : break-word ; padding : 1 em ; font-size : .8125 em }
. literalblock pre . nowrap , . literalblock pre [ class ] . nowrap , . listingblock pre . nowrap , . listingblock pre [ class ] . nowrap { overflow-x : auto ; white-space : pre ; word-wrap : normal }
@ media only screen and ( min-width : 768px ) {. literalblock pre , . literalblock pre [ class ], . listingblock pre , . listingblock pre [ class ] { font-size : .90625 em }}
@ media only screen and ( min-width : 1280px ) {. literalblock pre , . literalblock pre [ class ], . listingblock pre , . listingblock pre [ class ] { font-size : 1 em }}
. literalblock . output pre { color : #f7f7f8 ; background-color : rgba ( 0 , 0 , 0 , .9 )}
. listingblock pre . highlightjs { padding : 0 }
. listingblock pre . highlightjs > code { padding : 1 em ; -webkit- border-radius : 4 px ; border-radius : 4 px }
. listingblock pre . prettyprint { border-width : 0 }
. listingblock > . content { position : relative }
. listingblock code [ data-lang ] : before { display : none ; content : attr ( data - lang ); position : absolute ; font-size : .75 em ; top : .425 rem ; right : .5 rem ; line-height : 1 ; text-transform : uppercase ; color : #999 }
. listingblock : hover code [ data-lang ] : before { display : block }
. listingblock . terminal pre . command : before { content : attr ( data - prompt ); padding-right : .5 em ; color : #999 }
. listingblock . terminal pre . command : not ([ data-prompt ]) : before { content : "$" }
table . pyhltable { border-collapse : separate ; border : 0 ; margin-bottom : 0 ; background : none }
table . pyhltable td { vertical-align : top ; padding-top : 0 ; padding-bottom : 0 ; line-height : 1.45 }
table . pyhltable td . code { padding-left : .75 em ; padding-right : 0 }
pre . pygments . lineno , table . pyhltable td : not ( . code ) { color : #999 ; padding-left : 0 ; padding-right : .5 em ; border-right : 1 px solid #ddddd8 }
pre . pygments . lineno { display : inline-block ; margin-right : .25 em }
table . pyhltable . linenodiv { background : none !important ; padding-right : 0 !important }
. quoteblock { margin : 0 1 em 1.25 em 1.5 em ; display : table }
. quoteblock > . title { margin-left : -1.5 em ; margin-bottom : .75 em }
. quoteblock blockquote , . quoteblock blockquote p { color : rgba ( 0 , 0 , 0 , .85 ); font-size : 1.15 rem ; line-height : 1.75 ; word-spacing : .1 em ; letter-spacing : 0 ; font-style : italic ; text-align : justify }
. quoteblock blockquote { margin : 0 ; padding : 0 ; border : 0 }
. quoteblock blockquote : before { content : "\201c" ; float : left ; font-size : 2.75 em ; font-weight : bold ; line-height : .6 em ; margin-left : -.6 em ; color : #7a2518 ; text-shadow : 0 1 px 2 px rgba ( 0 , 0 , 0 , .1 )}
. quoteblock blockquote > . paragraph : last-child p { margin-bottom : 0 }
. quoteblock . attribution { margin-top : .5 em ; margin-right : .5 ex ; text-align : right }
. quoteblock . quoteblock { margin-left : 0 ; margin-right : 0 ; padding : .5 em 0 ; border-left : 3 px solid rgba ( 0 , 0 , 0 , .6 )}
. quoteblock . quoteblock blockquote { padding : 0 0 0 .75 em }
. quoteblock . quoteblock blockquote : before { display : none }
. verseblock { margin : 0 1 em 1.25 em 1 em }
. verseblock pre { font-family : "Open Sans" , "DejaVu Sans" , sans ; font-size : 1.15 rem ; color : rgba ( 0 , 0 , 0 , .85 ); font-weight : 300 ; text-rendering : optimizeLegibility }
. verseblock pre strong { font-weight : 400 }
. verseblock . attribution { margin-top : 1.25 rem ; margin-left : .5 ex }
. quoteblock . attribution , . verseblock . attribution { font-size : .9375 em ; line-height : 1.45 ; font-style : italic }
. quoteblock . attribution br , . verseblock . attribution br { display : none }
. quoteblock . attribution cite , . verseblock . attribution cite { display : block ; letter-spacing : -.025 em ; color : rgba ( 0 , 0 , 0 , .6 )}
. quoteblock . abstract { margin : 0 0 1.25 em 0 ; display : block }
. quoteblock . abstract blockquote , . quoteblock . abstract blockquote p { text-align : left ; word-spacing : 0 }
. quoteblock . abstract blockquote : before , . quoteblock . abstract blockquote p : first-of-type : before { display : none }
table . tableblock { max-width : 100 % ; border-collapse : separate }
table . tableblock td > . paragraph : last-child p > p : last-child , table . tableblock th > p : last-child , table . tableblock td > p : last-child { margin-bottom : 0 }
table . tableblock , th . tableblock , td . tableblock { border : 0 solid #dedede }
2017-07-17 19:28:36 +03:00
table . grid-all > thead > tr > . tableblock , table . grid-all > tbody > tr > . tableblock { border-width : 0 1 px 1 px 0 }
table . grid-all > tfoot > tr > . tableblock { border-width : 1 px 1 px 0 0 }
table . grid-cols >*> tr > . tableblock { border-width : 0 1 px 0 0 }
table . grid-rows > thead > tr > . tableblock , table . grid-rows > tbody > tr > . tableblock { border-width : 0 0 1 px 0 }
table . grid-rows > tfoot > tr > . tableblock { border-width : 1 px 0 0 0 }
table . grid-all >*> tr > . tableblock : last-child , table . grid-cols >*> tr > . tableblock : last-child { border-right-width : 0 }
table . grid-all > tbody > tr : last-child > . tableblock , table . grid-all > thead : last-child > tr > . tableblock , table . grid-rows > tbody > tr : last-child > . tableblock , table . grid-rows > thead : last-child > tr > . tableblock { border-bottom-width : 0 }
2017-06-07 00:02:25 +03:00
table . frame-all { border-width : 1 px }
table . frame-sides { border-width : 0 1 px }
table . frame-topbot { border-width : 1 px 0 }
th . halign-left , td . halign-left { text-align : left }
th . halign-right , td . halign-right { text-align : right }
th . halign-center , td . halign-center { text-align : center }
th . valign-top , td . valign-top { vertical-align : top }
th . valign-bottom , td . valign-bottom { vertical-align : bottom }
th . valign-middle , td . valign-middle { vertical-align : middle }
table thead th , table tfoot th { font-weight : bold }
tbody tr th { display : table-cell ; line-height : 1.6 ; background : #f7f8f7 }
tbody tr th , tbody tr th p , tfoot tr th , tfoot tr th p { color : rgba ( 0 , 0 , 0 , .8 ); font-weight : bold }
p . tableblock > code : only-child { background : none ; padding : 0 }
p . tableblock { font-size : 1 em }
td > div . verse { white-space : pre }
ol { margin-left : 1.75 em }
ul li ol { margin-left : 1.5 em }
dl dd { margin-left : 1.125 em }
dl dd : last-child , dl dd : last-child > : last-child { margin-bottom : 0 }
ol > li p , ul > li p , ul dd , ol dd , . olist . olist , . ulist . ulist , . ulist . olist , . olist . ulist { margin-bottom : .625 em }
2017-07-17 19:28:36 +03:00
ul . checklist , ul . none , ol . none , ul . no-bullet , ol . no-bullet , ol . unnumbered , ul . unstyled , ol . unstyled { list-style-type : none }
ul . no-bullet , ol . no-bullet , ol . unnumbered { margin-left : .625 em }
ul . unstyled , ol . unstyled { margin-left : 0 }
ul . checklist { margin-left : .625 em }
ul . checklist li > p : first-child > . fa-square-o : first-child , ul . checklist li > p : first-child > . fa-check-square-o : first-child { width : 1.25 em ; font-size : .8 em ; position : relative ; bottom : .125 em }
ul . checklist li > p : first-child > input [ type = "checkbox" ] : first-child { margin-right : .25 em }
2017-06-07 00:02:25 +03:00
ul . inline { margin : 0 auto .625 em auto ; margin-left : -1.375 em ; margin-right : 0 ; padding : 0 ; list-style : none ; overflow : hidden }
ul . inline > li { list-style : none ; float : left ; margin-left : 1.375 em ; display : block }
ul . inline > li >* { display : block }
. unstyled dl dt { font-weight : 400 ; font-style : normal }
ol . arabic { list-style-type : decimal }
ol . decimal { list-style-type : decimal-leading-zero }
ol . loweralpha { list-style-type : lower-alpha }
ol . upperalpha { list-style-type : upper-alpha }
ol . lowerroman { list-style-type : lower-roman }
ol . upperroman { list-style-type : upper-roman }
ol . lowergreek { list-style-type : lower-greek }
. hdlist > table , . colist > table { border : 0 ; background : none }
. hdlist > table > tbody > tr , . colist > table > tbody > tr { background : none }
td . hdlist1 , td . hdlist2 { vertical-align : top ; padding : 0 .625 em }
td . hdlist1 { font-weight : bold ; padding-bottom : 1.25 em }
. literalblock + . colist , . listingblock + . colist { margin-top : -.5 em }
2017-07-17 19:28:36 +03:00
. colist > table tr > td : first-of-type { padding : .4 em .75 em 0 .75 em ; line-height : 1 ; vertical-align : top }
. colist > table tr > td : first-of-type img { max-width : initial }
2017-06-07 00:02:25 +03:00
. colist > table tr > td : last-of-type { padding : .25 em 0 }
. thumb , . th { line-height : 0 ; display : inline-block ; border : solid 4 px #fff ; -webkit- box-shadow : 0 0 0 1 px #ddd ; box-shadow : 0 0 0 1 px #ddd }
. imageblock . left , . imageblock [ style *= "float: left" ] { margin : .25 em .625 em 1.25 em 0 }
. imageblock . right , . imageblock [ style *= "float: right" ] { margin : .25 em 0 1.25 em .625 em }
. imageblock > . title { margin-bottom : 0 }
. imageblock . thumb , . imageblock . th { border-width : 6 px }
. imageblock . thumb > . title , . imageblock . th > . title { padding : 0 .125 em }
. image . left , . image . right { margin-top : .25 em ; margin-bottom : .25 em ; display : inline-block ; line-height : 0 }
. image . left { margin-right : .625 em }
. image . right { margin-left : .625 em }
a . image { text-decoration : none ; display : inline-block }
a . image object { pointer-events : none }
sup . footnote , sup . footnoteref { font-size : .875 em ; position : static ; vertical-align : super }
sup . footnote a , sup . footnoteref a { text-decoration : none }
sup . footnote a : active , sup . footnoteref a : active { text-decoration : underline }
# footnotes { padding-top : .75 em ; padding-bottom : .75 em ; margin-bottom : .625 em }
# footnotes hr { width : 20 % ; min-width : 6.25 em ; margin : -.25 em 0 .75 em 0 ; border-width : 1 px 0 0 0 }
# footnotes . footnote { padding : 0 .375 em 0 .225 em ; line-height : 1.3334 ; font-size : .875 em ; margin-left : 1.2 em ; text-indent : -1.05 em ; margin-bottom : .2 em }
# footnotes . footnote a : first-of-type { font-weight : bold ; text-decoration : none }
# footnotes . footnote : last-of-type { margin-bottom : 0 }
# content # footnotes { margin-top : -.625 em ; margin-bottom : 0 ; padding : .75 em 0 }
. gist . file-data > table { border : 0 ; background : #fff ; width : 100 % ; margin-bottom : 0 }
. gist . file-data > table td . line-data { width : 99 % }
div . unbreakable { page-break-inside : avoid }
. big { font-size : larger }
. small { font-size : smaller }
. underline { text-decoration : underline }
. overline { text-decoration : overline }
. line-through { text-decoration : line-through }
. aqua { color : #00bfbf }
. aqua-background { background-color : #00fafa }
. black { color : #000 }
. black-background { background-color : #000 }
. blue { color : #0000bf }
. blue-background { background-color : #0000fa }
. fuchsia { color : #bf00bf }
. fuchsia-background { background-color : #fa00fa }
. gray { color : #606060 }
. gray-background { background-color : #7d7d7d }
. green { color : #006000 }
. green-background { background-color : #007d00 }
. lime { color : #00bf00 }
. lime-background { background-color : #00fa00 }
. maroon { color : #600000 }
. maroon-background { background-color : #7d0000 }
. navy { color : #000060 }
. navy-background { background-color : #00007d }
. olive { color : #606000 }
. olive-background { background-color : #7d7d00 }
. purple { color : #600060 }
. purple-background { background-color : #7d007d }
. red { color : #bf0000 }
. red-background { background-color : #fa0000 }
. silver { color : #909090 }
. silver-background { background-color : #bcbcbc }
. teal { color : #006060 }
. teal-background { background-color : #007d7d }
. white { color : #bfbfbf }
. white-background { background-color : #fafafa }
. yellow { color : #bfbf00 }
. yellow-background { background-color : #fafa00 }
span . icon > . fa { cursor : default }
2017-07-17 19:28:36 +03:00
a span . icon > . fa { cursor : inherit }
2017-06-07 00:02:25 +03:00
. admonitionblock td . icon [ class ^= "fa icon-" ] { font-size : 2.5 em ; text-shadow : 1 px 1 px 2 px rgba ( 0 , 0 , 0 , .5 ); cursor : default }
. admonitionblock td . icon . icon-note : before { content : "\f05a" ; color : #19407c }
. admonitionblock td . icon . icon-tip : before { content : "\f0eb" ; text-shadow : 1 px 1 px 2 px rgba ( 155 , 155 , 0 , .8 ); color : #111 }
. admonitionblock td . icon . icon-warning : before { content : "\f071" ; color : #bf6900 }
. admonitionblock td . icon . icon-caution : before { content : "\f06d" ; color : #bf3400 }
. admonitionblock td . icon . icon-important : before { content : "\f06a" ; color : #bf0000 }
. conum [ data-value ] { display : inline-block ; color : #fff !important ; background-color : rgba ( 0 , 0 , 0 , .8 ); -webkit- border-radius : 100 px ; border-radius : 100 px ; text-align : center ; font-size : .75 em ; width : 1.67 em ; height : 1.67 em ; line-height : 1.67 em ; font-family : "Open Sans" , "DejaVu Sans" , sans-serif ; font-style : normal ; font-weight : bold }
. conum [ data-value ] * { color : #fff !important }
. conum [ data-value ]+ b { display : none }
. conum [ data-value ] : after { content : attr ( data - value )}
pre . conum [ data-value ] { position : relative ; top : -.125 em }
b . conum * { color : inherit !important }
. conum : not ([ data-value ]) : empty { display : none }
dt , th . tableblock , td . content , div . footnote { text-rendering : optimizeLegibility }
h1 , h2 , p , td . content , span . alt { letter-spacing : -.01 em }
p strong , td . content strong , div . footnote strong { letter-spacing : -.005 em }
p , blockquote , dt , td . content , span . alt { font-size : 1.0625 rem }
p { margin-bottom : 1.25 rem }
. sidebarblock p , . sidebarblock dt , . sidebarblock td . content , p . tableblock { font-size : 1 em }
. exampleblock > . content { background-color : #fffef7 ; border-color : #e0e0dc ; -webkit- box-shadow : 0 1 px 4 px #e0e0dc ; box-shadow : 0 1 px 4 px #e0e0dc }
. print-only { display : none !important }
@ media print {@ page { margin : 1 . 25cm . 75cm }
* { -webkit- box-shadow : none !important ; box-shadow : none !important ; text-shadow : none !important }
a { color : inherit !important ; text-decoration : underline !important }
a . bare , a [ href ^= "#" ], a [ href ^= "mailto:" ] { text-decoration : none !important }
a [ href ^= "http:" ] : not ( . bare ) : after , a [ href ^= "https:" ] : not ( . bare ) : after { content : "(" attr ( href ) ")" ; display : inline-block ; font-size : .875 em ; padding-left : .25 em }
abbr [ title ] : after { content : " (" attr ( title ) ")" }
pre , blockquote , tr , img , object , svg { page-break-inside : avoid }
thead { display : table-header-group }
svg { max-width : 100 % }
p , blockquote , dt , td . content { font-size : 1 em ; orphans : 3 ; widows : 3 }
h2 , h3 , # toctitle , . sidebarblock > . content > . title { page-break-after : avoid }
# toc , . sidebarblock , . exampleblock > . content { background : none !important }
# toc { border-bottom : 1 px solid #ddddd8 !important ; padding-bottom : 0 !important }
. sect1 { padding-bottom : 0 !important }
. sect1 + . sect1 { border : 0 !important }
# header > h1 : first-child { margin-top : 1.25 rem }
body . book # header { text-align : center }
body . book # header > h1 : first-child { border : 0 !important ; margin : 2.5 em 0 1 em 0 }
body . book # header . details { border : 0 !important ; display : block ; padding : 0 !important }
body . book # header . details span : first-child { margin-left : 0 !important }
body . book # header . details br { display : block }
body . book # header . details br + span : before { content : none !important }
body . book # toc { border : 0 !important ; text-align : left !important ; padding : 0 !important ; margin : 0 !important }
body . book # toc , body . book # preamble , body . book h1 . sect0 , body . book . sect1 > h2 { page-break-before : always }
. listingblock code [ data-lang ] : before { display : block }
# footer { background : none !important ; padding : 0 .9375 em }
# footer-text { color : rgba ( 0 , 0 , 0 , .6 ) !important ; font-size : .9 em }
. hide-on-print { display : none !important }
. print-only { display : block !important }
. hide-for-print { display : none !important }
. show-for-print { display : inherit !important }}
</ style >
2017-03-14 22:57:07 +02:00
</ head >
2017-06-07 00:02:25 +03:00
< body class = "article toc2 toc-left" >
< div id = "header" >
2017-06-10 03:44:31 +03:00
< h1 > Boost.Mp11: A C++11 metaprogramming library</ h1 >
2017-06-07 00:02:25 +03:00
< div class = "details" >
< span id = "author" class = "author" > Peter Dimov</ span >< br >
</ div >
< div id = "toc" class = "toc2" >
< div id = "toctitle" > Table of Contents</ div >
< ul class = "sectlevel1" >
< li >< a href = "#overview" > Overview</ a ></ li >
< li >< a href = "#definitions" > Definitions</ a ></ li >
< li >< a href = "#examples" > Examples</ a >
< ul class = "sectlevel2" >
< li >< a href = "#generating_test_cases" > Generating Test Cases</ a ></ li >
2017-06-10 03:44:31 +03:00
< li >< a href = "#writing_common_type_specializations" > Writing common_type Specializations</ a ></ li >
< li >< a href = "#fixing_tuple_cat" > Fixing tuple_cat</ a ></ li >
2017-06-07 00:02:25 +03:00
< li >< a href = "#computing_return_types" > Computing Return Types</ a ></ li >
</ ul >
</ li >
< li >< a href = "#reference" > Reference</ a >
< ul class = "sectlevel2" >
< li >< a href = "#integral" > Integral Constants, < boost/mp11/integral.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_bool_b" > mp_bool< B> </ a ></ li >
< li >< a href = "#mp_true" > mp_true</ a ></ li >
< li >< a href = "#mp_false" > mp_false</ a ></ li >
< li >< a href = "#mp_to_bool_t" > mp_to_bool< T> </ a ></ li >
< li >< a href = "#mp_not_t" > mp_not< T> </ a ></ li >
< li >< a href = "#mp_int_i" > mp_int< I> </ a ></ li >
< li >< a href = "#mp_size_t_n" > mp_size_t< N> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#list" > List Operations, < boost/mp11/list.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_list_t" > mp_list< T…​> </ a ></ li >
< li >< a href = "#mp_size_l" > mp_size< L> </ a ></ li >
< li >< a href = "#mp_empty_l" > mp_empty< L> </ a ></ li >
< li >< a href = "#mp_front_l" > mp_front< L> </ a ></ li >
< li >< a href = "#mp_pop_front_l" > mp_pop_front< L> </ a ></ li >
< li >< a href = "#mp_first_l" > mp_first< L> </ a ></ li >
< li >< a href = "#mp_rest_l" > mp_rest< L> </ a ></ li >
< li >< a href = "#mp_second_l" > mp_second< L> </ a ></ li >
< li >< a href = "#mp_third_l" > mp_third< L> </ a ></ li >
< li >< a href = "#mp_push_front_l_t" > mp_push_front< L, T…​> </ a ></ li >
< li >< a href = "#mp_push_back_l_t" > mp_push_back< L, T…​> </ a ></ li >
< li >< a href = "#mp_rename_l_y" > mp_rename< L, Y> </ a ></ li >
< li >< a href = "#mp_apply_f_l" > mp_apply< F, L> </ a ></ li >
< li >< a href = "#mp_apply_q_q_l" > mp_apply_q< Q, L> </ a ></ li >
< li >< a href = "#mp_append_l" > mp_append< L…​> </ a ></ li >
< li >< a href = "#mp_replace_front_l_t" > mp_replace_front< L, T> </ a ></ li >
< li >< a href = "#mp_replace_first_l_t" > mp_replace_first< L, T> </ a ></ li >
< li >< a href = "#mp_replace_second_l_t" > mp_replace_second< L, T> </ a ></ li >
< li >< a href = "#mp_replace_third_l_t" > mp_replace_third< L, T> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#utility" > Utility Components, < boost/mp11/utility.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_identity_t" > mp_identity< T> </ a ></ li >
< li >< a href = "#mp_identity_t_t" > mp_identity_t< T> </ a ></ li >
< li >< a href = "#mp_inherit_t" > mp_inherit< T…​> </ a ></ li >
< li >< a href = "#mp_if_c_c_t_e" > mp_if_c< C, T, E…​> </ a ></ li >
< li >< a href = "#mp_if_c_t_e" > mp_if< C, T, E…​> </ a ></ li >
< li >< a href = "#mp_eval_if_c_c_t_f_u" > mp_eval_if_c< C, T, F, U…​> </ a ></ li >
< li >< a href = "#mp_eval_if_c_t_f_u" > mp_eval_if< C, T, F, U…​> </ a ></ li >
< li >< a href = "#mp_eval_if_q_c_t_q_u" > mp_eval_if_q< C, T, Q, U…​> </ a ></ li >
< li >< a href = "#mp_valid_f_t" > mp_valid< F, T…​> </ a ></ li >
< li >< a href = "#mp_defer_f_t" > mp_defer< F, T…​> </ a ></ li >
< li >< a href = "#mp_quote_f" > mp_quote< F> </ a ></ li >
2017-06-26 16:15:43 +03:00
< li >< a href = "#mp_quote_trait_f" > mp_quote_trait< F> </ a ></ li >
2017-06-07 00:02:25 +03:00
< li >< a href = "#mp_invoke_q_t" > mp_invoke< Q, T…​> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#algorithm" > Algorithms, < boost/mp11/algorithm.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_assign_l1_l2" > mp_assign< L1, L2> </ a ></ li >
< li >< a href = "#mp_clear_l" > mp_clear< L> </ a ></ li >
< li >< a href = "#mp_transform_f_l" > mp_transform< F, L…​> </ a ></ li >
< li >< a href = "#mp_transform_q_q_l" > mp_transform_q< Q, L…​> </ a ></ li >
< li >< a href = "#mp_transform_if_p_f_l" > mp_transform_if< P, F, L…​> </ a ></ li >
< li >< a href = "#mp_transform_if_q_qp_qf_l" > mp_transform_if_q< Qp, Qf, L…​> </ a ></ li >
< li >< a href = "#mp_fill_l_v" > mp_fill< L, V> </ a ></ li >
< li >< a href = "#mp_count_l_v" > mp_count< L, V> </ a ></ li >
< li >< a href = "#mp_count_if_l_p" > mp_count_if< L, P> </ a ></ li >
< li >< a href = "#mp_contains_l_v" > mp_contains< L, V> </ a ></ li >
< li >< a href = "#mp_repeat_c_l_n" > mp_repeat_c< L, N> </ a ></ li >
< li >< a href = "#mp_repeat_l_n" > mp_repeat< L, N> </ a ></ li >
< li >< a href = "#mp_product_f_l" > mp_product< F, L…​> </ a ></ li >
< li >< a href = "#mp_product_q_q_l" > mp_product_q< Q, L…​> </ a ></ li >
< li >< a href = "#mp_drop_c_l_n" > mp_drop_c< L, N> </ a ></ li >
< li >< a href = "#mp_drop_l_n" > mp_drop< L, N> </ a ></ li >
< li >< a href = "#mp_iota_c_n" > mp_iota_c< N> </ a ></ li >
< li >< a href = "#mp_iota_n" > mp_iota< N> </ a ></ li >
< li >< a href = "#mp_at_c_l_i" > mp_at_c< L, I> </ a ></ li >
< li >< a href = "#mp_at_l_i" > mp_at< L, I> </ a ></ li >
< li >< a href = "#mp_take_c_l_n" > mp_take_c< L, N> </ a ></ li >
< li >< a href = "#mp_take_l_n" > mp_take< L, N> </ a ></ li >
< li >< a href = "#mp_insert_c_l_i_t" > mp_insert_c< L, I, T…​> </ a ></ li >
< li >< a href = "#mp_insert_l_i_t" > mp_insert< L, I, T…​> </ a ></ li >
< li >< a href = "#mp_erase_c_l_i_j" > mp_erase_c< L, I, J> </ a ></ li >
< li >< a href = "#mp_erase_l_i_j" > mp_erase< L, I, J> </ a ></ li >
< li >< a href = "#mp_replace_l_v_w" > mp_replace< L, V, W> </ a ></ li >
< li >< a href = "#mp_replace_if_l_p_w" > mp_replace_if< L, P, W> </ a ></ li >
< li >< a href = "#mp_replace_at_c_l_i_w" > mp_replace_at_c< L, I, W> </ a ></ li >
< li >< a href = "#mp_replace_at_l_i_w" > mp_replace_at< L, I, W> </ a ></ li >
< li >< a href = "#mp_copy_if_l_p" > mp_copy_if< L, P> </ a ></ li >
< li >< a href = "#mp_remove_l_v" > mp_remove< L, V> </ a ></ li >
< li >< a href = "#mp_remove_if_l_p" > mp_remove_if< L, P> </ a ></ li >
< li >< a href = "#mp_partition_l_p" > mp_partition< L, P> </ a ></ li >
< li >< a href = "#mp_sort_l_p" > mp_sort< L, P> </ a ></ li >
< li >< a href = "#mp_find_l_v" > mp_find< L, V> </ a ></ li >
< li >< a href = "#mp_find_if_l_p" > mp_find_if< L, P> </ a ></ li >
< li >< a href = "#mp_reverse_l" > mp_reverse< L> </ a ></ li >
< li >< a href = "#mp_fold_l_v_f" > mp_fold< L, V, F> </ a ></ li >
< li >< a href = "#mp_reverse_fold_l_v_f" > mp_reverse_fold< L, V, F> </ a ></ li >
< li >< a href = "#mp_unique_l" > mp_unique< L> </ a ></ li >
< li >< a href = "#mp_all_of_l_p" > mp_all_of< L, P> </ a ></ li >
< li >< a href = "#mp_none_of_l_p" > mp_none_of< L, P> </ a ></ li >
< li >< a href = "#mp_any_of_l_p" > mp_any_of< L, P> </ a ></ li >
< li >< a href = "#mp_for_each_l_f" > mp_for_each< L> (f)</ a ></ li >
< li >< a href = "#mp_with_index_n_i_f" > mp_with_index< N> (i, f)</ a ></ li >
</ ul >
</ li >
< li >< a href = "#set" > Set Operations, < boost/mp11/set.hpp> </ a >
< ul class = "sectlevel3" >
2017-07-17 19:28:36 +03:00
< li >< a href = "#mp_is_set_s" > mp_is_set< S> </ a ></ li >
2017-06-07 00:02:25 +03:00
< li >< a href = "#mp_set_contains_s_v" > mp_set_contains< S, V> </ a ></ li >
< li >< a href = "#mp_set_push_back_s_t" > mp_set_push_back< S, T…​> </ a ></ li >
< li >< a href = "#mp_set_push_front_s_t" > mp_set_push_front< S, T…​> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#map" > Map Operations, < boost/mp11/map.hpp> </ a >
< ul class = "sectlevel3" >
2017-07-17 20:14:43 +03:00
< li >< a href = "#mp_is_map_m" > mp_is_map< M> </ a ></ li >
2017-06-07 00:02:25 +03:00
< li >< a href = "#mp_map_find_m_k" > mp_map_find< M, K> </ a ></ li >
< li >< a href = "#mp_map_contains_m_k" > mp_map_contains< M, K> </ a ></ li >
< li >< a href = "#mp_map_insert_m_t" > mp_map_insert< M, T> </ a ></ li >
< li >< a href = "#mp_map_replace_m_t" > mp_map_replace< M, T> </ a ></ li >
< li >< a href = "#mp_map_update_m_t_f" > mp_map_update< M, T, F> </ a ></ li >
< li >< a href = "#mp_map_erase_m_k" > mp_map_erase< M, K> </ a ></ li >
2017-07-17 19:46:51 +03:00
< li >< a href = "#mp_map_keys_m" > mp_map_keys< M> </ a ></ li >
2017-06-07 00:02:25 +03:00
</ ul >
</ li >
< li >< a href = "#function" > Helper Metafunctions, < boost/mp11/function.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_void_t" > mp_void< T…​> </ a ></ li >
< li >< a href = "#mp_and_t" > mp_and< T…​> </ a ></ li >
< li >< a href = "#mp_all_t" > mp_all< T…​> </ a ></ li >
< li >< a href = "#mp_or_t" > mp_or< T…​> </ a ></ li >
< li >< a href = "#mp_any_t" > mp_any< T…​> </ a ></ li >
< li >< a href = "#mp_same_t" > mp_same< T…​> </ a ></ li >
< li >< a href = "#mp_plus_t" > mp_plus< T…​> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#bind" > Bind, < boost/mp11/bind.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#mp_arg_i" > mp_arg< I> </ a ></ li >
< li >< a href = "#1_9" > _1, …​ , _9</ a ></ li >
< li >< a href = "#mp_bind_f_t" > mp_bind< F, T…​> </ a ></ li >
< li >< a href = "#mp_bind_q_q_t" > mp_bind_q< Q, T…​> </ a ></ li >
< li >< a href = "#mp_bind_front_f_t" > mp_bind_front< F, T…​> </ a ></ li >
< li >< a href = "#mp_bind_front_q_q_t" > mp_bind_front_q< Q, T…​> </ a ></ li >
< li >< a href = "#mp_bind_back_f_t" > mp_bind_back< F, T…​> </ a ></ li >
< li >< a href = "#mp_bind_back_q_q_t" > mp_bind_back_q< Q, T…​> </ a ></ li >
</ ul >
</ li >
< li >< a href = "#integer_sequence" > Integer Sequences, < boost/mp11/integer_sequence.hpp> </ a >
< ul class = "sectlevel3" >
< li >< a href = "#integer_sequence_t_i" > integer_sequence< T, I…​> </ a ></ li >
< li >< a href = "#make_integer_sequence_t_n" > make_integer_sequence< T, N> </ a ></ li >
< li >< a href = "#index_sequence_i" > index_sequence< I…​> </ a ></ li >
< li >< a href = "#make_index_sequence_n" > make_index_sequence< N> </ a ></ li >
< li >< a href = "#index_sequence_for_t" > index_sequence_for< T…​> </ a ></ li >
</ ul >
</ li >
2017-06-08 16:35:55 +03:00
< li >< a href = "#tuple" > Tuple Operations, < boost/mp11/tuple.hpp> </ a >
2017-06-07 00:02:25 +03:00
< ul class = "sectlevel3" >
2017-06-08 17:19:28 +03:00
< li >< a href = "#tuple_apply_f_tp" > tuple_apply(f, tp)</ a ></ li >
2017-06-08 19:22:53 +03:00
< li >< a href = "#construct_from_tuple_t_tp" > construct_from_tuple< T> (tp)</ a ></ li >
2017-06-07 00:02:25 +03:00
< li >< a href = "#tuple_for_each_tp_f" > tuple_for_each(tp, f)</ a ></ li >
</ ul >
</ li >
2017-07-20 21:05:31 +03:00
< li >< a href = "#mp11" > Convenience Header, < boost/mp11.hpp> </ a ></ li >
< li >< a href = "#mpl" > MPL Support, < boost/mp11/mpl.hpp> </ a ></ li >
2017-06-07 00:02:25 +03:00
</ ul >
</ li >
< li >< a href = "#copyright_and_license" > Appendix A: Copyright and License</ a ></ li >
</ ul >
</ div >
</ div >
< div id = "content" >
< div class = "sect1" >
< h2 id = "overview" > Overview</ h2 >
< div class = "sectionbody" >
< div class = "paragraph" >
2017-06-10 03:44:31 +03:00
< p > Mp11 is a C++11 metaprogramming library for compile-time manipulation of data structures
that contain types. It’ s based on template aliases and variadic templates and implements the
approach outlined in the article
2017-06-07 00:02:25 +03:00
< a href = "http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html" > "Simple C++ metaprogramming"</ a >
and < a href = "http://pdimov.com/cpp2/simple_cxx11_metaprogramming_2.html" > its sequel</ a > . Reading these
2017-06-07 00:39:45 +03:00
articles before proceeding with this documentation is < em > highly</ em > recommended.</ p >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "paragraph" >
< p > The general principles upon which Mp11 is built are that algorithms and metafunctions are
template aliases of the form < code > F< T…​> </ code > and data structures are lists of the form < code > L< T…​> </ code > ,
with the library placing no requirements on < code > L</ code > . < code > mp_list< T…​> </ code > is the built-in list type,
but < code > std::tuple< T…​> </ code > , < code > std::pair< T1, T2> </ code > and < code > std::variant< T…​> </ code > are also perfectly
legitimate list types, although of course < code > std::pair< T1, T2> </ code > , due to having exactly two elements,
is not resizeable and will consequently not work with algorithms that need to add or remove
elements.</ p >
</ div >
< div class = "paragraph" >
< p > Another distinguishing feature of this approach is that lists (< code > L< T…​> </ code > ) have the same form as
metafunctions (< code > F< T…​> </ code > ) and can therefore be used as such. For example, applying < code > std::add_pointer_t</ code >
to the list < code > std::tuple< int, float> </ code > by way of < code > mp_transform< std::add_pointer_t, std::tuple< int, float>> </ code >
gives us < code > std::tuple< int*, float*> </ code > , but we can also apply < code > mp_list</ code > to the same tuple:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > using R = mp_transform< mp_list, std::tuple< int, float>> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > and get < code > std::tuple< mp_list< int> , mp_list< float>> </ code > .</ p >
</ div >
</ div >
</ div >
< div class = "sect1" >
< h2 id = "definitions" > Definitions</ h2 >
< div class = "sectionbody" >
< div class = "paragraph" >
< p > A < em > list</ em > is a —  usually but not necessarily variadic —  template class whose parameters are all types,
for example < code > mp_list< char[], void> </ code > , < code > mp_list<> </ code > , < code > std::tuple< int, float, char> </ code > , < code > std::pair< int, float> </ code > , < code > std::shared_ptr< X> </ code > .</ p >
</ div >
< div class = "paragraph" >
< p > A < em > metafunction</ em > is a class template or a template alias whose parameters are all types, for example < code > std::add_pointer_t</ code > ,
< code > std::is_const</ code > , < code > mp_second</ code > , < code > mp_push_front</ code > , < code > mp_list</ code > , < code > std::tuple</ code > , < code > std::pair</ code > , < code > std::shared_ptr</ code > , or</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > template< class...> using F1 = void;
2017-06-07 00:02:25 +03:00
template< class T> using F2 = T*;
2017-06-10 03:44:31 +03:00
template< class... T> using F3 = std::integral_constant< std::size_t, sizeof...(T)> ;</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > A < em > quoted metafunction</ em > is a class with a public metafunction member called < code > fn</ code > , for example</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > struct Q1 { template< class...> using fn = void; };
2017-06-07 00:02:25 +03:00
struct Q2 { template< class T> using fn = T*; };
2017-06-10 03:44:31 +03:00
struct Q3 { template< class... T> using fn =
std::integral_constant< std::size_t, sizeof...(T)> ; };</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > An < em > integral constant type</ em > is a class with a public member < code > value</ code > that is an integral constant in the C++ sense. For example,
< code > std::integral_constant< int, 7> </ code > , or</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > struct N { static int constexpr value = 2; };</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > A < em > set</ em > is a list whose elements are unique.</ p >
</ div >
< div class = "paragraph" >
< p > A < em > map</ em > is a list of lists, the inner lists having at least one element (the key.) The keys of the map must be unique. For example,</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using M1 = std::tuple< std::pair< int, int*> , std::pair< float, float*> ,
std::pair< void, void*>> ;
using M2 = mp_list< mp_list< int, int*> , mp_list< float> ,
mp_list< char, char[1], char[2]>> ;</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
</ div >
< div class = "sect1" >
< h2 id = "examples" > Examples</ h2 >
< div class = "sectionbody" >
< div class = "sect2" >
< h3 id = "generating_test_cases" > Generating Test Cases</ h3 >
< div class = "paragraph" >
< p > Let’ s suppose that we have written a metafunction < code > result< T, U> </ code > :</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using promote = typename std::common_type< T, int> ::type;
2017-05-19 02:43:47 +03:00
2017-06-07 00:02:25 +03:00
template< class T, class U> using result =
typename std::common_type< promote< T> , promote< U>> ::type;</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > that ought to represent the result of an arithmetic operation on the integer types < code > T</ code > and < code > U</ code > ,
for example < code > t + u</ code > . We want to test whether < code > result< T, U> </ code > gives correct results for various combinations
of < code > T</ code > and < code > U</ code > , so we write the function</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class T1, class T2> void test_result()
{
using T3 = decltype( T1() + T2() );
using T4 = result< T1, T2> ;
2017-05-19 02:43:47 +03:00
2017-06-07 00:02:25 +03:00
std::cout << ( std::is_same< T3, T4> ::value? "[PASS]": "[FAIL]" ) << std::endl;
}</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > and then need to call it a substantial number of times:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > int main()
{
test_result< char, char> ();
test_result< char, short> ();
test_result< char, int> ();
test_result< char, unsigned> ();
// ...
}</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Writing all those type combinations by hand is unwieldy, error prone, and worst of all, boring. This is
how we can leverage Mp11 to automate the task:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > #include < boost/mp11.hpp>
#include < boost/core/demangle.hpp>
#include < type_traits>
#include < iostream>
#include < typeinfo>
2017-05-19 02:43:47 +03:00
2017-06-07 00:02:25 +03:00
using namespace boost::mp11;
2017-05-19 02:43:47 +03:00
2017-06-07 00:02:25 +03:00
template< class T> std::string name()
{
return boost::core::demangle( typeid(T).name() );
}
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T> using promote = typename std::common_type< T, int> ::type;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T, class U> using result =
typename std::common_type< promote< T> , promote< U>> ::type;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T1, class T2> void test_result( mp_list< T1, T2> const& )
{
using T3 = decltype( T1() + T2() );
using T4 = result< T1, T2> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
std::cout << ( std::is_same< T3, T4> ::value? "[PASS] ": "[FAIL] " )
<< name< T1> () << " + " << name< T2> () << " -> " << name< T3> ()
<< ", result: " << name< T4> () << std::endl;
}
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
int main()
{
using L = std::tuple< char, short, int, unsigned, long, unsigned long> ;
tuple_for_each( mp_product< mp_list, L, L> (), [](auto&& x){ test_result(x); } );
}</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > How does it work?</ p >
</ div >
< div class = "paragraph" >
< p >< code > mp_product< F, L1, L2> </ code > calls < code > F< T1, T2> </ code > where < code > T1</ code > varies over the elements of < code > L1</ code > and < code > T2</ code > varies over
the elements of < code > L2</ code > , as if by executing two nested loops. It then returns a list of these results, of the same
type as < code > L1</ code > .</ p >
</ div >
< div class = "paragraph" >
< p > In our case, both lists are the same < code > std::tuple</ code > , and < code > F</ code > is < code > mp_list</ code > , so < code > mp_product< mp_list, L, L> </ code > will get us
< code > std::tuple< mp_list< char, char> , mp_list< char, short> , mp_list< char, int> , …​ , mp_list< unsigned long, long> , mp_list< unsigned long, unsigned long>> </ code > .</ p >
</ div >
< div class = "paragraph" >
< p > We then default-construct this tuple and pass it to < code > tuple_for_each</ code > . < code > tuple_for_each(tp, f)</ code > calls < code > f</ code > for every
tuple element; we use a (C++14) lambda that calls < code > test_result</ code > .</ p >
</ div >
< div class = "paragraph" >
< p > In pure C++11, we can’ t use a lambda with an < code > auto&& </ code > parameter, so we’ ll have to make < code > test_result</ code > a function object with
a templated < code > operator()</ code > and pass that to < code > tuple_for_each</ code > directly:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > struct test_result
{
template< class T1, class T2> void operator()( mp_list< T1, T2> const& ) const
{
using T3 = decltype( T1() + T2() );
using T4 = result< T1, T2> ;
std::cout << ( std::is_same< T3, T4> ::value? "[PASS] ": "[FAIL] " )
<< name< T1> () << " + " << name< T2> () << " -> " << name< T3> ()
<< ", result: " << name< T4> () << std::endl;
}
};
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
int main()
{
using L = std::tuple< char, short, int, unsigned, long, unsigned long> ;
tuple_for_each( mp_product< mp_list, L, L> (), test_result() );
}</ code ></ pre >
</ div >
</ div >
</ div >
< div class = "sect2" >
2017-06-10 03:44:31 +03:00
< h3 id = "writing_common_type_specializations" > Writing common_type Specializations</ h3 >
2017-06-07 00:02:25 +03:00
< div class = "paragraph" >
< p > The standard trait < code > std::common_type</ code > , used to obtain a type to which all of its arguments can convert without
unnecessary loss of precision, can be user-specialized when its default implementation (based on the ternary < code > ?:</ code >
operator) is unsuitable.</ p >
</ div >
< div class = "paragraph" >
< p > Let’ s write a < code > common_type</ code > specialization for two < code > std::tuple</ code > arguments. For that, we need a metafunction that
applies < code > std::common_type</ code > to each pair of elements and gathers the results into a tuple:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class... T> using common_type_t =
typename std::common_type< T...> ::type; // standard in C++14
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class Tp1, class Tp2> using common_tuple =
mp_transform< common_type_t, Tp1, Tp2> ;</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > then specialize < code > common_type</ code > to use it:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > namespace std
{
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class... T1, class... T2>
struct common_type< std::tuple< T1...> , std::tuple< T2...>> :
mp_defer< common_tuple, std::tuple< T1...> , std::tuple< T2...>>
{
};
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
} // std</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > (There is no need to specialize < code > std::common_type</ code > for more than two arguments - it takes care of synthesizing the appropriate semantics from
the binary case.)</ p >
</ div >
< div class = "paragraph" >
< p > The subtlety here is the use of < code > mp_defer</ code > . We could have defined a nested < code > type</ code > to < code > common_tuple< std::tuple< T1…​> , std::tuple< T2…​>> </ code > ,
and it would still have worked in all valid cases. By letting < code > mp_defer</ code > define < code > type</ code > , though, we make our specialization < em > SFINAE-friendly</ em > .</ p >
</ div >
< div class = "paragraph" >
< p > That is, when our < code > common_tuple</ code > causes a substitution failure instead of a hard error, < code > mp_defer</ code > will not define a nested < code > type</ code > ,
and < code > common_type_t</ code > , which is defined as < code > typename common_type<…​> ::type</ code > , will also cause a substitution failure.</ p >
</ div >
< div class = "paragraph" >
< p > As another example, consider the hypothetical type < code > expected< T, E…​> </ code > that represents either a successful return with a value of < code > T</ code > ,
or an unsucessful return with an error code of some type in the list < code > E…​ </ code > . The common type of < code > expected< T1, E1, E2, E3> </ code > and
< code > expected< T2, E1, E4, E5> </ code > is < code > expected< common_type_t< T1, T2> , E1, E2, E3, E4, E5> </ code > . That is, the possible return values are
combined into their common type, and we take the union of the set of error types.</ p >
</ div >
< div class = "paragraph" >
< p > Therefore,</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class T1, class E1, class T2, class E2> using common_expected =
2017-06-10 03:44:31 +03:00
mp_rename< mp_push_front< mp_unique< mp_append< E1, E2>> , common_type_t< T1, T2>> ,
expected> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
namespace std
{
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T1, class... E1, class T2, class... E2>
struct common_type< expected< T1, E1...> , expected< T2, E2...>> :
mp_defer< common_expected, T1, mp_list< E1...> , T2, mp_list< E2...>>
{
};
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
} // std</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Here we’ ve taken a different tack; instead of passing the < code > expected</ code > types to < code > common_expected</ code > , we’ re passing the < code > T</ code > types and lists of
the < code > E</ code > types. This makes our job easier. < code > mp_unique< mp_append< E1, E2>> </ code > gives us the concatenation of < code > E1</ code > and < code > E2</ code > with the duplicates
removed; we then add < code > common_type_t< T1, T2> </ code > to the front via < code > mp_push_front</ code > ; and finally, we < code > mp_rename</ code > the resultant < code > mp_list</ code >
to < code > expected</ code > .</ p >
</ div >
</ div >
< div class = "sect2" >
2017-06-10 03:44:31 +03:00
< h3 id = "fixing_tuple_cat" > Fixing tuple_cat</ h3 >
2017-06-07 00:02:25 +03:00
< div class = "paragraph" >
< p > The article < a href = "http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html#" > Simple C++11 metaprogramming</ a > builds an
implementation of the standard function < code > tuple_cat</ code > , with the end result given below:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class L> using F = mp_iota< mp_size< L>> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class R, class...Is, class... Ks, class Tp>
R tuple_cat_( mp_list< Is...> , mp_list< Ks...> , Tp tp )
{
return R{ std::get< Ks::value> (std::get< Is::value> (tp))... };
}
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class... Tp,
class R = mp_append< std::tuple<> , typename std::remove_reference< Tp> ::type...>>
R tuple_cat( Tp && ... tp )
{
std::size_t const N = sizeof...(Tp);
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
// inner
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
using list1 = mp_list<
mp_rename< typename std::remove_reference< Tp> ::type, mp_list> ...> ;
2017-06-07 00:02:25 +03:00
using list2 = mp_iota_c< N> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using list3 = mp_transform< mp_fill, list1, list2> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using inner = mp_apply< mp_append, list3> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
// outer
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using list4 = mp_transform< F, list1> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using outer = mp_apply< mp_append, list4> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
//
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
return tuple_cat_< R> ( inner(), outer(),
std::forward_as_tuple( std::forward< Tp> (tp)... ) );
2017-06-07 00:02:25 +03:00
}</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > This function, however, is not entirely correct, in that it doesn’ t handle some cases properly. For example,
trying to concatenate tuples containing move-only elements such as < code > unique_ptr</ code > fails:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > std::tuple< std::unique_ptr< int>> t1;
std::tuple< std::unique_ptr< float>> t2;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
auto result = ::tuple_cat( std::move( t1 ), std::move( t2 ) );</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Trying to concatenate < code > const</ code > tuples fails:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > std::tuple< int> const t1;
std::tuple< float> const t2;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
auto result = ::tuple_cat( t1, t2 );</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > And finally, the standard < code > tuple_cat</ code > is specified to work on arbitrary tuple-like types (that is, all types
that support < code > tuple_size</ code > , < code > tuple_element</ code > , and < code > get</ code > ), while our implementation only works with < code > tuple</ code > and
< code > pair</ code > . < code > std::array</ code > , for example, fails:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > std::array< int, 2> t1{ 1, 2 };
std::array< float, 3> t2{ 3.0f, 4.0f, 5.0f };
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
auto result = ::tuple_cat( t1, t2 );</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Let’ s fix these one by one. Support for move-only types is easy, if one knows where to look. The problem is
that < code > Tp</ code > that we’ re passing to the helper < code > tuple_cat_</ code > is (correctly) < code > tuple< unique_ptr< int>&& , unique_ptr< float>&&> </ code > ,
but < code > std::get< 0> (tp)</ code > still returns < code > unique_ptr< int>& </ code > , because < code > tp</ code > is an lvalue. This behavior is a bit
2017-06-10 03:44:31 +03:00
surprising, but is intended to prevent inadvertent double moves.</ p >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "paragraph" >
< p > Long story short, we need < code > std::move(tp)</ code > in < code > tuple_cat_</ code > to make < code > tp</ code > an rvalue:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class R, class...Is, class... Ks, class Tp>
R tuple_cat_( mp_list< Is...> , mp_list< Ks...> , Tp tp )
{
return R{ std::get< Ks::value> (std::get< Is::value> (std::move(tp)))... };
}</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Next, < code > const</ code > -qualified tuples. The issue here is that we’ re stripping references from the input tuples, but not
< code > const</ code > . As a result, we’ re trying to manipulate types such as < code > tuple< int> const</ code > with Mp11 algorithms, and these
types do not fit the list concept. We just need to strip qualifiers as well, by defining the useful < code > remove_cv_ref</ code >
primitive that is inexplicably missing from the standard library:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T> using remove_cv_ref = typename std::remove_cv<
typename std::remove_reference< T> ::type> ::type;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > and then by using < code > remove_cv_ref< Tp> </ code > in place of < code > typename std::remove_reference< Tp> ::type</ code > :</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class... Tp,
class R = mp_append< std::tuple<> , remove_cv_ref< Tp> ...>>
R tuple_cat( Tp && ... tp )
{
std::size_t const N = sizeof...(Tp);
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
// inner
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using list1 = mp_list< mp_rename< remove_cv_ref< Tp> , mp_list> ...> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
// ...</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Finally, tuple-like types. We’ ve so far exploited the fact that < code > std::pair</ code > and < code > std::tuple</ code > are valid Mp11 lists,
but in general, arbitrary tuple-like types aren’ t, so we need to convert them into such. For that, we’ ll need to
define a metafunction < code > from_tuple_like</ code > that will take an arbitrary tuple-like type and will return, in our case,
the corresponding < code > mp_list</ code > .</ p >
</ div >
< div class = "paragraph" >
< p > Technically, a more principled approach would’ ve been to return < code > std::tuple</ code > , but here < code > mp_list</ code > will prove more
convenient.</ p >
</ div >
< div class = "paragraph" >
< p > What we need is, given a tuple-like type < code > Tp</ code > , to obtain < code > mp_list< std::tuple_element< 0, Tp> ::type, std::tuple_element< 1, Tp> ::type,
…​ , std::tuple_element< N-1, Tp> ::type> </ code > , where < code > N</ code > is < code > tuple_size< Tp> ::value</ code > . Here’ s one way to do it:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class T, class I> using tuple_element =
typename std::tuple_element< I::value, T> ::type;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T> using from_tuple_like =
mp_product< tuple_element, mp_list< T> , mp_iota< std::tuple_size< T>>> ;</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > (< code > mp_iota< N> </ code > is an algorithm that returns an < code > mp_list</ code > with elements < code > mp_size_t< 0> </ code > , < code > mp_size_t< 1> </ code > , …​ , < code > mp_size_t< N-1> </ code > .)</ p >
</ div >
< div class = "paragraph" >
< p > Remember that < code > mp_product< F, L1, L2> </ code > performs the equivalent of two nested loops over the elements of < code > L1</ code > and < code > L2</ code > ,
applying < code > F</ code > to the two variables and gathering the result. In our case < code > L1</ code > consists of the single element < code > T</ code > , so
only the second loop (over < code > mp_iota< N> </ code > , where < code > N</ code > is < code > tuple_size< T> </ code > ), remains, and we get a list of the same type
as < code > L1</ code > (an < code > mp_list</ code > ) with contents < code > tuple_element< T, mp_size_t< 0>> </ code > , < code > tuple_element< T, mp_size_t< 1>> </ code > , …​ ,
< code > tuple_element< T, mp_size_t< N-1>> </ code > .</ p >
</ div >
< div class = "paragraph" >
< p > For completeness’ s sake, here’ s another, more traditional way to achieve the same result:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T> using from_tuple_like =
mp_transform_q< mp_bind_front< tuple_element, T> , mp_iota< std::tuple_size< T>>> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > With all these fixes applied, our fully operational < code > tuple_cat</ code > now looks like this:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class L> using F = mp_iota< mp_size< L>> ;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
template< class R, class...Is, class... Ks, class Tp>
R tuple_cat_( mp_list< Is...> , mp_list< Ks...> , Tp tp )
{
return R{ std::get< Ks::value> (std::get< Is::value> (std::move(tp)))... };
}
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
template< class T> using remove_cv_ref = typename std::remove_cv<
typename std::remove_reference< T> ::type> ::type;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
template< class T, class I> using tuple_element =
typename std::tuple_element< I::value, T> ::type;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
template< class T> using from_tuple_like =
mp_product< tuple_element, mp_list< T> , mp_iota< std::tuple_size< T>>> ;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
template< class... Tp,
class R = mp_append< std::tuple<> , from_tuple_like< remove_cv_ref< Tp>> ...>>
R tuple_cat( Tp && ... tp )
{
std::size_t const N = sizeof...(Tp);
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
// inner
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
using list1 = mp_list< from_tuple_like< remove_cv_ref< Tp>> ...> ;
using list2 = mp_iota_c< N> ;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
using list3 = mp_transform< mp_fill, list1, list2> ;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
using inner = mp_apply< mp_append, list3> ;
2017-03-17 05:55:27 +02:00
2017-06-07 00:02:25 +03:00
// outer
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using list4 = mp_transform< F, list1> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using outer = mp_apply< mp_append, list4> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
//
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
return tuple_cat_< R> ( inner(), outer(),
std::forward_as_tuple( std::forward< Tp> (tp)... ) );
2017-06-07 00:02:25 +03:00
}</ code ></ pre >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "computing_return_types" > Computing Return Types</ h3 >
< div class = "paragraph" >
< p > C++17 has a standard variant type, called < code > std::variant</ code > . It also defines a function template
< code > std::visit</ code > that can be used to apply a function to the contained value of one or more variants.
So for instance, if the variant < code > v1</ code > contains < code > 1</ code > , and the variant < code > v2</ code > contains < code > 2.0f</ code > ,
< code > std::visit(f, v1, v2)</ code > will call < code > f(1, 2.0f)</ code > .</ p >
</ div >
< div class = "paragraph" >
< p > However, < code > std::visit</ code > has one limitation: it cannot return a result unless all
possible applications of the function have the same return type. If, for instance, < code > v1</ code > and < code > v2</ code >
are both of type < code > std::variant< short, int, float> </ code > ,</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > std::visit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > will fail to compile because the result of < code > x + y</ code > can be either < code > int</ code > or < code > float</ code > depending on
what < code > v1</ code > and < code > v2</ code > hold.</ p >
</ div >
< div class = "paragraph" >
< p > A type that can hold either < code > int</ code > or < code > float</ code > already exists, called, surprisingly enough, < code > std::variant< int, float> </ code > .
Let’ s write our own function template < code > rvisit</ code > that is the same as < code > visit</ code > but returns a < code > variant</ code > :</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > template< class F, class... V> auto rvisit( F&& f, V&& ... v )
{
using R = /*...*/;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
return std::visit( [& ]( auto&& ... x )
{ return R( std::forward< F> (f)( std::forward< decltype(x)> (x)... ) ); },
std::forward< V> ( v )... );
}</ code ></ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > What this does is basically calls < code > std::visit</ code > to do the work, but instead of passing it < code > f</ code > , we pass a lambda that does the same as < code > f</ code > except
it converts the result to a common type < code > R</ code > . < code > R</ code > is supposed to be < code > std::variant<…​> </ code > where the ellipsis denotes the return types of
calling < code > f</ code > with all possible combinations of variant values.</ p >
</ div >
< div class = "paragraph" >
< p > We’ ll first define a helper quoted metafunction < code > Qret< F> </ code > that returns the result of the application of < code > F</ code > to arguments of type < code > T…​ </ code > :</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class F> struct Qret
{
2017-06-10 03:44:31 +03:00
template< class... T> using fn =
decltype( std::declval< F> ()( std::declval< T> ()... ) );
2017-06-07 00:02:25 +03:00
};</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > (Unfortunately, we can’ t just define this metafunction inside < code > rvisit</ code > ; the language prohibits defining template aliases inside functions.)</ p >
</ div >
< div class = "paragraph" >
< p > With < code > Qret</ code > in hand, a < code > variant</ code > of the possible return types is just a matter of applying it over the possible combinations of the variant values:</ p >
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > using R = mp_product_q< Qret< F> , std::remove_reference_t< V> ...> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Why does this work? < code > mp_product< F, L1< T1…​> , L2< T2…​> , …​ , Ln< Tn…​>> </ code > returns < code > L1< F< U1, U2, …​ , Un> , …​> </ code > , where < code > Ui</ code > traverse all
possible combinations of list values. Since in our case all < code > Li</ code > are < code > std::variant</ code > , the result will also be < code > std::variant</ code > . (< code > mp_product_q</ code > is
the same as < code > mp_product</ code > , but for quoted metafunctions such as our < code > Qret< F> </ code > .)</ p >
</ div >
< div class = "paragraph" >
< p > One more step remains. Suppose that, as above, we’ re passing two variants of type < code > std::variant< short, int, float> </ code > and < code > F</ code > is
< code > []( auto const& x, auto const& y ){ return x + y; }</ code > . This will generate < code > R</ code > of length 9, one per each combination, but many of those
2017-06-10 03:44:31 +03:00
elements will be the same, either < code > int</ code > or < code > float</ code > , and we need to filter out the duplicates. So, we pass the result to < code > mp_unique</ code > :</ p >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "literalblock" >
< div class = "content" >
< pre > using R = mp_unique< mp_product_q< Qret< F> , std::remove_reference_t< V> ...>> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > and we’ re done:</ p >
</ div >
< div class = "listingblock" >
< div class = "content" >
< pre class = "highlight" >< code > #include < boost/mp11.hpp>
#include < boost/core/demangle.hpp>
#include < variant>
#include < type_traits>
#include < typeinfo>
#include < iostream>
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using namespace boost::mp11;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class F> struct Qret
{
2017-06-10 03:44:31 +03:00
template< class... T> using fn =
decltype( std::declval< F> ()( std::declval< T> ()... ) );
2017-06-07 00:02:25 +03:00
};
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class F, class... V> auto rvisit( F&& f, V&& ... v )
{
using R = mp_unique< mp_product_q< Qret< F> , std::remove_reference_t< V> ...>> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
return std::visit( [& ]( auto&& ... x )
{ return R( std::forward< F> (f)( std::forward< decltype(x)> (x)... ) ); },
std::forward< V> ( v )... );
}
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
template< class T> std::string name()
{
return boost::core::demangle( typeid(T).name() );
}
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
template< class V> void print_variant( char const * n, V const& v )
{
std::cout << "(" << name< decltype(v)> () << ")" << n << ": ";
std::visit( []( auto const& x )
{ std::cout << "(" << name< decltype(x)> () << ")" << x << std::endl; }, v );
}
2017-06-07 00:02:25 +03:00
int main()
{
2017-06-10 03:44:31 +03:00
std::variant< char, int, float> v1( 1 );
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
print_variant( "v1", v1 );
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
std::variant< short, int, double> v2( 3.14 );
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
print_variant( "v2", v2 );
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
auto v3 = rvisit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );
2017-05-17 20:47:25 +03:00
2017-06-10 03:44:31 +03:00
print_variant( "v3", v3 );
2017-06-07 00:02:25 +03:00
}</ code ></ pre >
</ div >
</ div >
</ div >
</ div >
</ div >
< div class = "sect1" >
< h2 id = "reference" > Reference</ h2 >
< div class = "sectionbody" >
< div class = "paragraph" >
< p > The contents of the library are in namespace < code > boost::mp11</ code > .</ p >
</ div >
< div class = "sect2" >
< h3 id = "integral" > Integral Constants, < boost/mp11/integral.hpp> </ h3 >
< div class = "paragraph" >
< p > For an Mp11 integral constant type < code > T</ code > , < code > T::value</ code > is an integral constant in the C++ sense.</ p >
</ div >
< div class = "sect3" >
< h4 id = "mp_bool_b" > mp_bool< B> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< bool B> using mp_bool = std::integral_constant< bool, B> ;</ pre >
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "paragraph" >
< p > Same as < code > std::bool_constant</ code > in C++17.</ p >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_true" > mp_true</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > using mp_true = mp_bool< true> ;</ pre >
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "paragraph" >
< p > Same as < code > std::true_type</ code > .</ p >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_false" > mp_false</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > using mp_false = mp_bool< false> ;</ pre >
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "paragraph" >
< p > Same as < code > std::false_type</ code > .</ p >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_to_bool_t" > mp_to_bool< T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T> using mp_to_bool = mp_bool< static_cast< bool> (T::value)> ;</ pre >
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_not_t" > mp_not< T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T> using mp_not = mp_bool< !T::value > ;</ pre >
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_int_i" > mp_int< I> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< int I> using mp_int = std::integral_constant< int, I> ;</ pre >
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_size_t_n" > mp_size_t< N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< std::size_t N> using mp_size_t = std::integral_constant< std::size_t, N> ;</ pre >
</ div >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "list" > List Operations, < boost/mp11/list.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "mp_list_t" > mp_list< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> struct mp_list {};</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_list</ code > is the standard list type of Mp11, although the library is not restricted to it and can operate on arbitrary class templates
such as < code > std::tuple</ code > or < code > std::variant</ code > . Even < code > std::pair</ code > can be used if the transformation does not alter the number of the elements in
the list.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_size_l" > mp_size< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_size = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_size< L> </ code > returns the number of elements in the list < code > L</ code > , as a < code > mp_size_t</ code > . In other words, < code > mp_size< L< T…​>> </ code > is an alias for
< code > mp_size_t< sizeof…​ (T)> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 1. Using mp_size with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = mp_list<> ;
using R1 = mp_size< L1> ; // mp_size_t< 0> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 2. Using mp_size with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::pair< int, int> ;
using R2 = mp_size< L2> ; // mp_size_t< 2> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 3. Using mp_size with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L3 = std::tuple< float> ;
using R3 = mp_size< L3> ; // mp_size_t< 1> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_empty_l" > mp_empty< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_empty = mp_bool< mp_size< L> ::value == 0> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_empty< L> </ code > is an alias for < code > mp_true</ code > if the list < code > L</ code > is empty, for < code > mp_false</ code > otherwise.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 4. Using mp_empty with std::tuple</ div >
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< float> ;
using R1 = mp_empty< L1> ; // mp_false
using L2 = std::tuple<> ;
using R2 = mp_empty< L2> ; // mp_true</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_front_l" > mp_front< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_front = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_front< L> </ code > is the first element of the list < code > L</ code > . That is, < code > mp_front< L< T1, T…​>> </ code > is an alias for < code > T1</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 5. Using mp_front with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< int, float> ;
using R1 = mp_front< L1> ; // int</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 6. Using mp_front with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::tuple< float, double, long double> ;
using R2 = mp_front< L2> ; // float</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 7. Using mp_front with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L3 = mp_list< char[1], char[2], char[3], char[4]> ;
using R3 = mp_front< L3> ; // char[1]</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_pop_front_l" > mp_pop_front< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_pop_front = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_pop_front< L> </ code > removes the first element of the list < code > L</ code > . That is, < code > mp_pop_front< L< T1, T…​>> </ code > is an alias for < code > L< T…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 8. Using mp_pop_front with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::tuple< float, double, long double> ;
using R1 = mp_pop_front< L1> ; // std::tuple< double, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 9. Using mp_pop_front with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = mp_list< void> ;
using R2 = mp_pop_front< L2> ; // mp_list<> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_first_l" > mp_first< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_first = mp_front< L> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_first</ code > is another name for < code > mp_front</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_rest_l" > mp_rest< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_rest = mp_pop_front< L> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_rest</ code > is another name for < code > mp_pop_front</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_second_l" > mp_second< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_second = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_second< L> </ code > is the second element of the list < code > L</ code > . That is, < code > mp_second< L< T1, T2, T…​>> </ code > is an alias for < code > T2</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 10. Using mp_second with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< int, float> ;
using R1 = mp_second< L1> ; // float</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 11. Using mp_second with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::tuple< float, double, long double> ;
using R2 = mp_second< L2> ; // double</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 12. Using mp_second with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L3 = mp_list< char[1], char[2], char[3], char[4]> ;
using R3 = mp_second< L3> ; // char[2]</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_third_l" > mp_third< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_third = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_third< L> </ code > is the third element of the list < code > L</ code > . That is, < code > mp_third< L< T1, T2, T3, T…​>> </ code > is an alias for < code > T3</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 13. Using mp_third with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::tuple< float, double, long double> ;
using R1 = mp_third< L1> ; // long double</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 14. Using mp_third with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = mp_list< char[1], char[2], char[3], char[4]> ;
using R2 = mp_third< L2> ; // char[3]</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_push_front_l_t" > mp_push_front< L, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class... T> using mp_push_front = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_push_front< L, T…​> </ code > inserts the elements < code > T…​ </ code > at the front of the list < code > L</ code > . That is, < code > mp_push_front< L< U…​> , T…​> </ code >
is an alias for < code > L< T…​ , U…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 15. Using mp_push_front with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::tuple< double, long double> ;
using R1 = mp_push_front< L1, float> ; // std::tuple< float, double, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 16. Using mp_push_front with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = mp_list< void> ;
using R2 = mp_push_front< L2, char[1], char[2]> ; // mp_list< char[1], char[2], void> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_push_back_l_t" > mp_push_back< L, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class... T> using mp_push_back = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_push_back< L, T…​> </ code > inserts the elements < code > T…​ </ code > at the back of the list < code > L</ code > . That is, < code > mp_push_back< L< U…​> , T…​> </ code >
is an alias for < code > L< U…​ , T…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 17. Using mp_push_back with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::tuple< double, long double> ;
using R1 = mp_push_back< L1, float> ; // std::tuple< double, long double, float> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 18. Using mp_push_back with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = mp_list< void> ;
using R2 = mp_push_back< L2, char[1], char[2]> ; // mp_list< void, char[1], char[2]> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_rename_l_y" > mp_rename< L, Y> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class Y> using mp_rename = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_rename< L, Y> </ code > changes the type of the list < code > L</ code > to < code > Y</ code > . That is, < code > mp_rename< L< T…​> , Y> </ code > is an alias for < code > Y< T…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 19. Using mp_rename to rename std::pair to std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< double, long double> ;
using R1 = mp_rename< L1, std::tuple> ; // std::tuple< double, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 20. Using mp_rename to rename std::tuple to mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::tuple< void> ;
using R2 = mp_rename< L2, mp_list> ; // mp_list< void> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_apply_f_l" > mp_apply< F, L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class L> using mp_apply = mp_rename< L, F> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_apply< F, L> </ code > applies the metafunction < code > F</ code > to the contents of the list < code > L</ code > , that is, < code > mp_apply< F, L< T…​>> </ code > is an alias for < code > F< T…​> </ code > .
(< code > mp_apply</ code > is the same as < code > mp_rename</ code > with the arguments reversed.)</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 21. Using mp_apply with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< double, long double> ;
using R1 = mp_apply< std::is_same, L1> ; // std::is_same< double, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_apply_q_q_l" > mp_apply_q< Q, L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class Q, class L> using mp_apply_q = mp_apply< Q::template fn, L> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_apply</ code > , but takes a quoted metafunction.</ p >
</ div >
< div class = "listingblock" >
2017-06-10 03:44:31 +03:00
< div class = "title" > Code Example 22. Using mp_apply_q with mp_bind_front</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< double, long double> ;
using L2 = mp_list< int, long> ;
2017-05-17 20:47:25 +03:00
2017-06-07 00:02:25 +03:00
using R1 = mp_apply_q< mp_bind_front< mp_push_back, L1> , L2> ;
2017-06-10 03:44:31 +03:00
// R1 is std::tuple< double, long double, int, long> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_append_l" > mp_append< L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... L> using mp_append = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_append< L…​> </ code > concatenates the lists in < code > L…​ </ code > into a single list that has the same type as the first list. < code > mp_append<> </ code >
is an alias for < code > mp_list<> </ code > . < code > mp_append< L1< T1…​> , L2< T2…​> , …​ , Ln< Tn…​>> </ code > is an alias for < code > L1< T1…​ , T2…​ , …​ , Tn…​> </ code > .</ p >
</ div >
< div class = "listingblock" >
2017-06-10 03:44:31 +03:00
< div class = "title" > Code Example 23. Using mp_append with lists of various types</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< double, long double> ;
using L2 = mp_list< int> ;
using L3 = std::pair< short, long> ;
using L4 = mp_list<> ;
2017-05-18 14:59:46 +03:00
2017-06-10 03:44:31 +03:00
using R1 = mp_append< L1, L2, L3, L4> ;
// std::tuple< double, long double, int, short, long> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_front_l_t" > mp_replace_front< L, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class T> using mp_replace_front = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_replace_front< L, T> </ code > replaces the first element of the list < code > L</ code > with < code > T</ code > . That is, < code > mp_replace_front< L< U1, U…​> , T> </ code > is
an alias for < code > L< T, U…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 24. Using mp_replace_front with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< int, float> ;
using R1 = mp_replace_front< L1, void> ; // std::pair< void, float> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 25. Using mp_replace_front with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::tuple< float, double, long double> ;
using R2 = mp_replace_front< L2, void> ; // std::tuple< void, double, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 26. Using mp_replace_front with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L3 = mp_list< char[1], char[2], char[3], char[4]> ;
using R3 = mp_replace_front< L3, void> ; // mp_list< void, char[2], char[3], char[4]> ;</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_first_l_t" > mp_replace_first< L, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class T> using mp_replace_first = mp_replace_front< L, T> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_replace_first</ code > is another name for < code > mp_replace_front</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_second_l_t" > mp_replace_second< L, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class T> using mp_replace_second = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_replace_second< L, T> </ code > replaces the second element of the list < code > L</ code > with < code > T</ code > . That is, < code > mp_replace_second< L< U1, U2, U…​> , T> </ code >
is an alias for < code > L< U1, T, U…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 27. Using mp_replace_second with std::pair</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::pair< int, float> ;
using R1 = mp_replace_second< L1, void> ; // std::pair< int, void> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 28. Using mp_replace_second with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = std::tuple< float, double, long double> ;
using R2 = mp_replace_second< L2, void> ; // std::tuple< float, void, long double> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 29. Using mp_replace_front with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L3 = mp_list< char[1], char[2], char[3], char[4]> ;
using R3 = mp_replace_second< L3, void> ; // mp_list< char[1], void, char[3], char[4]> ;</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_third_l_t" > mp_replace_third< L, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class T> using mp_replace_third = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_replace_third< L, T> </ code > replaces the third element of the list < code > L</ code > with < code > T</ code > . That is, < code > mp_replace_third< L< U1, U2, U3, U…​> , T> </ code >
is an alias for < code > L< U1, U2, T, U…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 30. Using mp_replace_third with std::tuple</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L1 = std::tuple< float, double, long double> ;
using R1 = mp_replace_third< L1, void> ; // std::tuple< float, double, void> </ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 31. Using mp_replace_third with mp_list</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using L2 = mp_list< char[1], char[2], char[3], char[4]> ;
using R2 = mp_replace_third< L2, void> ; // mp_list< char[1], char[2], void, char[4]> ;</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "utility" > Utility Components, < boost/mp11/utility.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "mp_identity_t" > mp_identity< T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T> struct mp_identity
{
using type = T;
};</ pre >
</ div >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "paragraph" >
< p >< code > mp_identity</ code > is a simple < em > transformation type trait</ em > (as per the C++ standard)
that just returns the same type. It’ s useful both as such, and as a type wrapper
useful for passing types as values to functions.</ p >
</ div >
< div class = "listingblock" >
< div class = "title" > Code Example 32. Using mp_identity as a type trait</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using addp_if_not_ref =
typename mp_if< std::is_reference< T> , mp_identity< T> , std::add_pointer< T>> ::type;</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
< div class = "title" > Code Example 33. Using mp_identity to protect qualifiers and references</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class T> void print1()
{
std::cout << typeid(T).name() << std::endl;
}
template< class T> void print2()
{
std::cout << typeid(mp_identity< T> ).name() << std::endl;
}
int main()
{
print1< int const&> (); // 'int'
print2< int const&> (); // 'mp_identity< int const &> '
}</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_identity_t_t" > mp_identity_t< T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 04:13:39 +03:00
< pre > template< class T> using mp_identity_t = typename mp_identity< T> ::type;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_inherit_t" > mp_inherit< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> struct mp_inherit: T... {};</ pre >
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_if_c_c_t_e" > mp_if_c< C, T, E…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< bool C, class T, class... E> using mp_if_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_if_c< true, T, E…​> </ code > is an alias for < code > T</ code > . < code > mp_if_c< false, T, E> </ code > is an alias for < code > E</ code > . Otherwise, the result is a substitution failure.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 34. Using mp_if_c to select between two alternatives</ div >
< div class = "content" >
< pre class = "highlight" >< code > using R1 = mp_if_c< true, int, void> ; // int
using R2 = mp_if_c< false, int, void> ; // void</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
< div class = "title" > Code Example 35. Using mp_if_c to fail substitution when a condition is not met</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class I> using void_if_5 = mp_if_c< I::value == 5, void> ;</ code ></ pre >
</ div >
</ div >
2017-06-09 20:35:21 +03:00
< div class = "paragraph" >
2017-06-10 03:44:31 +03:00
< p > This example returns < code > void</ code > when < code > I::value</ code > is 5, and generates a substitution failure
otherwise. It’ s the same as < code > std::enable_if_t< I::value == 5> </ code > in C++14, or
< code > typename std::enable_if< I::value == 5> ::type</ code > in C++11.</ p >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_if_c_t_e" > mp_if< C, T, E…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class C, class T, class E...> using mp_if =
mp_if_c< static_cast< bool> (C::value), T, E...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Like < code > mp_if_c</ code > , but the first argument is a type.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 36. Using mp_if to select between two alternatives</ div >
< div class = "content" >
< pre class = "highlight" >< code > using R1 = mp_if< mp_true, int, void> ; // int
using R2 = mp_if< mp_false, int, void> ; // void</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
< div class = "title" > Code Example 37. Using mp_if to fail substitution when a condition is not met</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using void_if_const = mp_if< std::is_const< T> , void> ;
template< class... T> using void_if_all_const =
mp_if< mp_all< std::is_const< T> ...> , void> ;
template< class T> using if_non_const = mp_if< mp_not< std::is_const< T>> , T> ;</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_eval_if_c_c_t_f_u" > mp_eval_if_c< C, T, F, U…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< bool C, class T, template< class...> class F, class... U> using mp_eval_if_c =
/*...*/;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_eval_if_c< C, T, F, U…​> </ code > is an alias for < code > T</ code > when < code > C</ code > is < code > true</ code > , for < code > F< U…​> </ code > otherwise. Its purpose
is to avoid evaluating < code > F< U…​> </ code > when the condition is < code > true</ code > as it may not be valid in this case.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 38. Using mp_eval_if_c to select the first pack element, or void</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class... T> using first_or_void =
mp_eval_if_c< sizeof...(T) == 0, void, mp_apply, mp_first, mp_list< T...>> ;</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_eval_if_c_t_f_u" > mp_eval_if< C, T, F, U…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class C, class T, template< class...> class F, class... U> using mp_eval_if =
mp_eval_if_c< static_cast< bool> (C::value), T, F, U...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Like < code > mp_eval_if_c</ code > , but the first argument is a type.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 39. Using mp_eval_if to select the first list element, or void</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class L> using first_or_void = mp_eval_if< mp_empty< L> , void, mp_first, L> ;</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_eval_if_q_c_t_q_u" > mp_eval_if_q< C, T, Q, U…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class C, class T, class Q, class... U> using mp_eval_if_q =
mp_eval_if< C, T, Q::template fn, U...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Like < code > mp_eval_if</ code > , but takes a quoted metafunction.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_valid_f_t" > mp_valid< F, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... T> using mp_valid = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_valid< F, T…​> </ code > is an alias for < code > mp_true</ code > when < code > F< T…​> </ code > is a valid expression, for < code > mp_false</ code > otherwise.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 40. Using mp_valid to write a metafunction that checks for the existence of a nested type</ div >
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using get_nested_type = typename T::type;
template< class T> struct has_nested_type: mp_valid< get_nested_type, T> {};</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_defer_f_t" > mp_defer< F, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... T> using mp_defer = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > When < code > mp_valid< F, T…​> </ code > is < code > mp_true</ code > , < code > mp_defer< F, T…​> </ code > is a struct with a nested type < code > type</ code > which is an alias for < code > F< T…​> </ code > . Otherwise,
< code > mp_defer< F, T…​> </ code > is an empty struct.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_quote_f" > mp_quote< F> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F> struct mp_quote
{
template< class... T> using fn = F< T...> ;
};</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_quote< F> </ code > transforms the template < code > F</ code > into a type with a nested template < code > fn</ code > such that < code > fn< T…​> </ code > returns < code > F< T…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
< div class = "title" > Code Example 41. Using mp_quote to make a list of metafunctions</ div >
< div class = "content" >
< pre class = "highlight" >< code > using LQ = mp_list< mp_quote< std::is_const> , mp_quote< std::is_volatile>> ;</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
2017-06-26 16:15:43 +03:00
< h4 id = "mp_quote_trait_f" > mp_quote_trait< F> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F> struct mp_quote_trait
{
template< class... T> using fn = typename F< T...> ::type;
};</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_quote_trait< F> </ code > transforms the C++03-style trait < code > F</ code > into a quoted metafunction.</ p >
</ div >
< div class = "listingblock" >
< div class = "title" > Code Example 42. Using mp_quote_trait with std::add_pointer</ div >
< div class = "content" >
< pre class = "highlight" >< code > using L1 = mp_list< int, void, float> ;
using R1 = mp_transform_q< mp_quote_trait< std::add_pointer> , L1> ;
// mp_list< int*, void*, float*> </ code ></ pre >
</ div >
</ div >
</ div >
< div class = "sect3" >
2017-06-07 00:02:25 +03:00
< h4 id = "mp_invoke_q_t" > mp_invoke< Q, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class Q, class... T> using mp_invoke = typename Q::template fn< T...> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_invoke< Q, T…​> </ code > evaluates the nested template < code > fn</ code > of a quoted metafunction. < code > mp_invoke< mp_quote< F> , T…​> </ code > returns < code > F< T…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 43. Using mp_invoke to invoke a list of metafunctions, technique 1</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using LQ = mp_list< mp_quote< std::is_const> , mp_quote< std::is_volatile>> ;
template< class T> using is_const_and_volatile =
mp_all< mp_product< mp_invoke, LQ, mp_list< T>>> ;</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 44. Using mp_invoke to invoke a list of metafunctions, technique 2</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using is_const_and_volatile =
mp_all< mp_transform_q< mp_bind_back< mp_invoke, T> , LQ>> ;</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 45. Using mp_invoke to invoke a list of metafunctions, technique 3</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using is_const_and_volatile =
mp_all< mp_transform< mp_invoke, LQ, mp_fill< LQ, T>>> ;</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "sect2" >
< h3 id = "algorithm" > Algorithms, < boost/mp11/algorithm.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "mp_assign_l1_l2" > mp_assign< L1, L2> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L1, class L2> using mp_assign = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_assign< L1< T1…​> , L2< T2…​>> </ code > is an alias for < code > L1< T2…​> </ code > . That is, it replaces the elements of < code > L1</ code > with those of < code > L2</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 46. Using mp_assign with mp_list and std::tuple</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< long> ;
using L2 = mp_list< int, float> ;
using R1 = mp_assign< L1, L2> ; // std::tuple< int, float> </ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 47. Using mp_assign with mp_list and std::pair</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::pair< long, char> ;
using L2 = mp_list< int, float> ;
using R1 = mp_assign< L1, L2> ; // std::pair< int, float> </ code ></ pre >
</ div >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 1. mp_assign</ caption >
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_assign< L1, L2> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_clear_l" > mp_clear< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_clear = mp_assign< L, mp_list<>> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_clear< L< T…​>> </ code > is an alias for < code > L<> </ code > , that is, it removes the elements of < code > L</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 48. Using mp_clear with std::tuple</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< int, float> ;
using R1 = mp_clear< L1> ; // std::tuple<> </ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_transform_f_l" > mp_transform< F, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... L> using mp_transform = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_transform< F, L1< T1…​> , L2< T2…​> , …​ , Ln< Tn…​>> </ code > applies < code > F</ code > to each successive tuple of elements and returns < code > L1< F< T1, T2, …​ , Tn>…​> </ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 49. Using mp_transform to produce a list of pointers from a list of pointees</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class T> using add_pointer_t =
typename std::add_pointer< T> ::type; // std::add_pointer_t in C++14
using L1 = std::tuple< void, int, float> ;
using R1 = mp_transform< add_pointer_t, L1> ; // std::tuple< void*, int*, float*> </ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 50. Using mp_transform to compare the contents of two lists of types</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< void, int, float> ;
using L2 = mp_list< void, int, float> ;
using R1 = mp_all< mp_transform< std::is_same, L1, L2>> ; // mp_true</ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 51. Using mp_transform to compare the contents of two lists of integral constants</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class T1, class T2> using eq = mp_bool< T1::value == T2::value> ;
using L1 = std::tuple< mp_int< 1> , mp_int< 2> , mp_int< 3>> ;
using L2 = mp_list< mp_size_t< 1> , mp_size_t< 2> , mp_size_t< 3>> ;
using R1 = mp_all< mp_transform< eq, L1, L2>> ; // mp_true</ code ></ pre >
</ div >
</ div >
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-11 04:35:34 +03:00
< caption class = "title" > Illustration 2. mp_transform on one list</ caption >
2017-06-10 03:44:31 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_transform< F, L1> </ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > n</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
</ tbody >
</ table >
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-11 04:35:34 +03:00
< caption class = "title" > Illustration 3. mp_transform on two lists</ caption >
2017-06-10 03:44:31 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_transform< F, L1, L2> </ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 1</ sub > ,B< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > n</ sub > ,B< sub > n</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_transform_q_q_l" > mp_transform_q< Q, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class Q, class... L> using mp_transform_q =
mp_transform< Q::template fn, L...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > As < code > mp_transform</ code > , but takes a quoted metafunction.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 52. Using mp_transform_q to count the occurences of < code > void</ code > in a list</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< void, int, float, void, int> ;
using R1 = mp_apply< mp_plus,
mp_transform_q< mp_bind_front< std::is_same, void> , L1>> ; // mp_int< 2> </ code ></ pre >
</ div >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 4. mp_transform_q on two lists</ caption >
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_transform_q< Q, L1, L2> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > Q::fn< A< sub > 1</ sub > ,B< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > Q::fn< A< sub > 2</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > Q::fn< A< sub > n</ sub > ,B< sub > n</ sub > > </ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_transform_if_p_f_l" > mp_transform_if< P, F, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< template< class...> class P, template< class...> class F, class L...>
using mp_transform_if = /*...*/;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_transform_if< P, F, L1, L2, …​ , Ln> </ code > replaces the elements of the list < code > L1</ code > for which < code > mp_to_bool< P< T1, T2, …​ , Tn>> </ code > is < code > mp_true</ code > with
< code > F< T1, T2, …​ , Tn> </ code > , and returns the result, where < code > Ti</ code > are the corresponding elements of < code > Li</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 53. Using mp_transform_if to replace the occurences of 'void' in a list with the corresponding elements of a second list</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< void, int, float, void, int> ;
using L2 = std::tuple< char[1], char[2], char[3], char[4], char[5]> ;
template< class T1, class T2> using first_is_void = std::is_same< T1, void> ;
template< class T1, class T2> using second = T2;
using R1 = mp_transform_if< first_is_void, second, L1, L2> ;
// std::tuple< char[1], int, float, char[4], int> </ code ></ pre >
</ div >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 5. mp_transform_if</ caption >
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > P< A< sub > i</ sub > > </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_true</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_transform_if< P, F, L1, L2> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_transform_if_q_qp_qf_l" > mp_transform_if_q< Qp, Qf, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class Qp, class Qf, class... L> using mp_transform_if_q =
mp_transform_if< Qp::template fn, Qf::template fn, L...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
2017-06-10 03:44:31 +03:00
< p > As < code > mp_transform_if</ code > , but takes quoted metafunctions.</ p >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 54. Using mp_transform_if_q to replace the occurences of 'void' in a list with the corresponding elements of a second list</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< void, int, float, void, int> ;
using L2 = std::tuple< char[1], char[2], char[3], char[4], char[5]> ;
using R1 = mp_transform_if_q< mp_bind< std::is_same, _1, void> , _2, L1, L2> ;
// std::tuple< char[1], int, float, char[4], int> </ code ></ pre >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 6. mp_transform_if_q</ caption >
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > Qp::fn< A< sub > i</ sub > > </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_true</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_transform_if_q< Qp, _2, L1, L2> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_fill_l_v" > mp_fill< L, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V> using mp_fill = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_fill< L< T…​> , V> </ code > returns < code > L< V, V, …​ , V> </ code > , with the result having the same size as the input.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 55. Using mp_fill with std::tuple</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::tuple< void, int, float> ;
using R1 = mp_fill< L1, double> ; // std::tuple< double, double, double> </ code ></ pre >
</ div >
</ div >
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 56. Using mp_fill with std::pair</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > using L1 = std::pair< int, float> ;
using R1 = mp_fill< L1, void> ; // std::pair< void, void> </ code ></ pre >
</ div >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 7. mp_fill</ caption >
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_fill< L1, V> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > V</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > V</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > V</ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_count_l_v" > mp_count< L, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V> using mp_count = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_count< L, V> </ code > returns < code > mp_size_t< N> </ code > , where < code > N</ code > is the number of elements of < code > L</ code > same as < code > V</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_count_if_l_p" > mp_count_if< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_count_if = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_count_if< L, P> </ code > returns < code > mp_size_t< N> </ code > , where < code > N</ code > is the number of elements < code > T</ code > of < code > L</ code > for which < code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_contains_l_v" > mp_contains< L, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V> using mp_contains = mp_to_bool< mp_count< L, V>> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_contains< L, V> </ code > is < code > mp_true</ code > when < code > L</ code > contains an element < code > V</ code > , < code > mp_false</ code > otherwise.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_repeat_c_l_n" > mp_repeat_c< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, std::size_t N> using mp_repeat_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_repeat_c< L, N> </ code > returns a list of the same type as < code > L</ code > that consists of < code > N</ code > concatenated copies of < code > L</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_repeat_l_n" > mp_repeat< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class N> using mp_repeat = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_repeat_c</ code > but with a type argument < code > N</ code > . The number of copies is < code > N::value</ code > and must be nonnegative.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_product_f_l" > mp_product< F, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... L> using mp_product = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_product< F, L1< T1…​> , L2< T2…​> , …​ , Ln< Tn…​>> </ code > evaluates < code > F< U1, U2, …​ , Un> </ code > for values < code > Ui</ code > taken from
the Cartesian product of the lists, as if the elements < code > Ui</ code > are formed by < code > n</ code > nested loops, each traversing < code > Li</ code > .
It returns a list of type < code > L1</ code > containing the results of the application of < code > F</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-11 04:35:34 +03:00
< caption class = "title" > Illustration 8. mp_product on two lists</ caption >
2017-06-10 03:44:31 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L2</ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > m</ sub ></ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_product< F, L1, L2> </ strong ></ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 1</ sub > ,B< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 1</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
2017-06-11 04:35:34 +03:00
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 1</ sub > ,B< sub > m</ sub > > </ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > ,B< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > 2</ sub > ,B< sub > m</ sub > > </ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" ></ td >
< td class = "tableblock halign-center valign-middle" colspan = "4" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > n</ sub > ,B< sub > 1</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > n</ sub > ,B< sub > 2</ sub > > </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > F< A< sub > n</ sub > ,B< sub > m</ sub > > </ code ></ p ></ td >
2017-06-10 03:44:31 +03:00
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_product_q_q_l" > mp_product_q< Q, L…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class Q, class... L> using mp_product_q = mp_product< Q::template fn, L...> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > As < code > mp_product</ code > , but takes a quoted metafunction.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_drop_c_l_n" > mp_drop_c< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, std::size_t N> using mp_drop_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_drop_c< L, N> </ code > removes the first < code > N</ code > elements of < code > L</ code > and returns the result.</ p >
</ div >
2017-06-17 18:53:10 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 9. mp_drop_c</ caption >
< colgroup >
< col style = "width: 40%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m+1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "7" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_drop_c< L1, M> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m+1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" colspan = "3" ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_drop_l_n" > mp_drop< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class N> using mp_drop = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_drop_c</ code > , but with a type argument < code > N</ code > . < code > N::value</ code > must be a nonnegative number.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_iota_c_n" > mp_iota_c< N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< std::size_t N> using mp_iota_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_iota_c< N> </ code > is an alias for < code > mp_list< mp_size_t< 0> , mp_size_t< 1> , …​ , mp_size_t< N-1>> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_iota_n" > mp_iota< N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class N> using mp_iota = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_iota_c</ code > , but with a type argument < code > N</ code > . < code > N::value</ code > must be a nonnegative number. Returns
< code > mp_list< std::integral_constant< T, 0> , std::integral_constant< T, 1> , …​ , std::integral_constant< T, N::value-1>> </ code >
where < code > T</ code > is the type of < code > N::value</ code > .</ p >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-17 18:53:10 +03:00
< caption class = "title" > Illustration 10. mp_iota</ caption >
2017-06-11 04:35:34 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_iota< mp_int< 4>> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_int< 0> </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_int< 1> </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_int< 2> </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_int< 3> </ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_at_c_l_i" > mp_at_c< L, I> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, std::size_t I> using mp_at_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
2017-06-10 03:44:31 +03:00
< p >< code > mp_at_c< L, I> </ code > returns the < code > I</ code > -th element of < code > L</ code > , zero-based.</ p >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_at_l_i" > mp_at< L, I> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class I> using mp_at = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_at_c</ code > , but with a type argument < code > I</ code > . < code > I::value</ code > must be a nonnegative number.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_take_c_l_n" > mp_take_c< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, std::size_t N> using mp_take_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_take_c< L, N> </ code > returns a list of the same type as < code > L</ code > containing the first < code > N</ code > elements of < code > L</ code > .</ p >
</ div >
2017-06-17 18:53:10 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 11. mp_take_c</ caption >
< colgroup >
< col style = "width: 40%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
< col style = "width: 10%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m+1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "7" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_take_c< L1, M> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" colspan = "3" ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_take_l_n" > mp_take< L, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class N> using mp_take = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_take_c</ code > , but with a type argument < code > N</ code > . < code > N::value</ code > must be a nonnegative number.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_insert_c_l_i_t" > mp_insert_c< L, I, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, std::size_t I, class... T> using mp_insert_c =
mp_append< mp_take_c< L, I> , mp_push_front< mp_drop_c< L, I> , T...>> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Inserts the elements < code > T…​ </ code > into the list < code > L</ code > at position < code > I</ code > (a zero-based index).</ p >
</ div >
2017-06-17 18:53:10 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 12. mp_insert_c with two elements</ caption >
< colgroup >
< col style = "width: 33.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3333%;" >
< col style = "width: 8.3336%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m+1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" colspan = "2" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "9" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_insert_c< L1, M, B< sub > 1</ sub > , B< sub > 2</ sub > > </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > B< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > m+1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_insert_l_i_t" > mp_insert< L, I, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, class I, class... T> using mp_insert =
mp_append< mp_take< L, I> , mp_push_front< mp_drop< L, I> , T...>> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_insert_c</ code > , but with a type argument < code > I</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_erase_c_l_i_j" > mp_erase_c< L, I, J> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, std::size_t I, std::size_t J> using mp_erase_c =
mp_append< mp_take_c< L, I> , mp_drop_c< L, J>> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Removes from the list < code > L</ code > the elements with indices from < code > I</ code > (inclusive) to < code > J</ code > (exclusive).</ p >
</ div >
2017-06-17 18:53:10 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
< caption class = "title" > Illustration 13. mp_erase_c</ caption >
< colgroup >
< col style = "width: 30.7692%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6923%;" >
< col style = "width: 7.6924%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 0</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > i-1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > i</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > j-1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > j</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n-1</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "10" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_erase_c< L1, I, J> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 0</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > i-1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > j</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n-1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" colspan = "3" ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_erase_l_i_j" > mp_erase< L, I, J> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, class I, class J> using mp_erase =
mp_append< mp_take< L, I> , mp_drop< L, J>> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_erase_c</ code > , but with a type arguments < code > I</ code > and < code > J</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_l_v_w" > mp_replace< L, V, W> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V, class W> using mp_replace = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Replaces all < code > V</ code > elements of < code > L</ code > with < code > W</ code > and returns the result.</ p >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-17 18:53:10 +03:00
< caption class = "title" > Illustration 14. mp_replace</ caption >
2017-06-11 04:35:34 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > V</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_replace< L1, V, W> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > W</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_if_l_p_w" > mp_replace_if< L, P, W> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P, class W> using mp_replace_if = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Replaces all < code > T</ code > elements of < code > L</ code > for which < code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code > with < code > W</ code > and returns the result.</ p >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-17 18:53:10 +03:00
< caption class = "title" > Illustration 15. mp_replace_if</ caption >
2017-06-11 04:35:34 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > P< A< sub > i</ sub > > </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_true</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > mp_false</ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_replace_if< L1, P, W> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > W</ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_at_c_l_i_w" > mp_replace_at_c< L, I, W> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, std::size_t I, class W> using mp_replace_at_c = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Replaces the element of < code > L</ code > at zero-based index < code > I</ code > with < code > W</ code > and returns the result.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_replace_at_l_i_w" > mp_replace_at< L, I, W> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class I, class W> using mp_replace_at = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > mp_replace_at_c</ code > , but with a type argument < code > I</ code > . < code > I::value</ code > must be a nonnegative number.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_copy_if_l_p" > mp_copy_if< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_copy_if = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Copies the elements < code > T</ code > of < code > L</ code > for which < code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code > to a new list of the same type and returns it.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_remove_l_v" > mp_remove< L, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V> using mp_remove = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Removes all < code > V</ code > elements of < code > L</ code > and returns the result.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_remove_if_l_p" > mp_remove_if< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_remove_if = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Removes all elements < code > T</ code > of < code > L</ code > for which < code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code > and returns the result.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_partition_l_p" > mp_partition< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_partition = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_partition< L< T…​> , P> </ code > partitions < code > L</ code > into two lists < code > L< U1…​> </ code > and < code > L< U2…​> </ code > such that < code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code >
for the elements of < code > L< U1…​> </ code > and < code > mp_false</ code > for the elements of < code > L< U2…​> </ code > . Returns < code > L< L< U1…​> , L< U2…​>> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_sort_l_p" > mp_sort< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_sort = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_sort< L, P> </ code > sorts the list < code > L</ code > according to the strict weak ordering < code > mp_to_bool< P< T, U>> </ code > .</ p >
</ div >
2017-06-09 20:35:21 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 57. Using mp_sort to sort a list of std::ratio values</ div >
2017-06-09 20:35:21 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > #include < ratio>
2017-06-09 20:35:21 +03:00
using L1 = mp_list< std::ratio< 1,2> , std::ratio< 1,4>> ;
2017-06-10 03:44:31 +03:00
using R1 = mp_sort< L1, std::ratio_less> ; // mp_list< ratio< 1,4> , ratio< 1,2>> </ pre >
2017-06-09 20:35:21 +03:00
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_find_l_v" > mp_find< L, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V> using mp_find = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_find< L, V> </ code > returns the index at which the type < code > V</ code > is located in the list < code > L</ code > . It’ s an alias for < code > mp_size_t< I> </ code > ,
where < code > I</ code > is the zero-based index of the first occurence of < code > V</ code > in < code > L</ code > . If < code > L</ code > does not contain < code > V</ code > , < code > mp_find< L, V> </ code >
is < code > mp_size< L> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_find_if_l_p" > mp_find_if< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, template< class...> class P> using mp_find_if = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_find_f< L, P> </ code > is an alias for < code > mp_size_t< I> </ code > , where < code > I</ code > is the zero-based index of the first element < code > T</ code > in < code > L</ code > for which
< code > mp_to_bool< P< T>> </ code > is < code > mp_true</ code > . If there is no such element, < code > mp_find_if< L, P> </ code > is < code > mp_size< L> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_reverse_l" > mp_reverse< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_reverse = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_reverse< L< T1, T2, …​ , Tn>> </ code > is < code > L< Tn, …​ , T2, T1> </ code > .</ p >
</ div >
2017-06-11 04:35:34 +03:00
< table class = "tableblock frame-all grid-all" style = "width: 85%;" >
2017-06-17 18:53:10 +03:00
< caption class = "title" > Illustration 16. mp_reverse</ caption >
2017-06-11 04:35:34 +03:00
< colgroup >
< col style = "width: 50%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
< col style = "width: 12.5%;" >
</ colgroup >
< tbody >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > L1</ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 2</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" colspan = "5" ></ td >
</ tr >
< tr >
< td class = "tableblock halign-left valign-middle" >< p class = "tableblock" >< code >< strong > mp_reverse< L1> </ strong ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > n-1</ sub ></ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > …​ </ code ></ p ></ td >
< td class = "tableblock halign-center valign-middle" >< p class = "tableblock" >< code > A< sub > 1</ sub ></ code ></ p ></ td >
</ tr >
</ tbody >
</ table >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_fold_l_v_f" > mp_fold< L, V, F> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class V, template< class...> class F> using mp_fold = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_fold< L< T1, T2, …​ , Tn> , V, F> </ code > is < code > F< F< F< F< V, T1> , T2> , …​> , Tn> </ code > , or < code > V</ code > , if < code > L</ code > is empty.</ p >
</ div >
2017-06-17 19:39:13 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 58. Using mp_fold to add the contents of a list of std::ratio values</ div >
2017-06-17 19:39:13 +03:00
< div class = "content" >
< pre > #include < ratio>
using L1 = mp_list< std::ratio< 1,8> , std::ratio< 1,4> , std::ratio< 1,2>> ;
using R1 = mp_fold< L1, std::ratio< 0,1> , std::ratio_add> ; // std::ratio< 7,8> </ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_reverse_fold_l_v_f" > mp_reverse_fold< L, V, F> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class L, class V, template< class...> class F> using mp_reverse_fold =
/*...*/;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_reverse_fold< L< T1, T2, …​ , Tn> , V, F> </ code > is < code > F< T1, F< T2, F<…​ , F< Tn, V>>>> </ code > , or < code > V</ code > , if < code > L</ code > is empty.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_unique_l" > mp_unique< L> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L> using mp_unique = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_unique< L> </ code > returns a list of the same type as < code > L</ code > with the duplicate elements removed.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_all_of_l_p" > mp_all_of< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, template< class...> class P> using mp_all_of =
mp_bool< mp_count_if< L, P> ::value == mp_size< L> ::value > ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_all_of< L, P> </ code > is < code > mp_true</ code > when < code > P</ code > holds for all elements of < code > L</ code > , < code > mp_false</ code > otherwise. When < code > L</ code > is empty, the result is < code > mp_true</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_none_of_l_p" > mp_none_of< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, template< class...> class P> using mp_none_of =
mp_bool< mp_count_if< L, P> ::value == 0 > ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_none_of< L, P> </ code > is < code > mp_true</ code > when < code > P</ code > holds for no element of < code > L</ code > , < code > mp_false</ code > otherwise. When < code > L</ code > is empty, the result is < code > mp_true</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_any_of_l_p" > mp_any_of< L, P> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class L, template< class...> class P> using mp_any_of =
mp_bool< mp_count_if< L, P> ::value != 0 > ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_any_of< L, P> </ code > is < code > mp_true</ code > when < code > P</ code > holds for at least one element of < code > L</ code > , < code > mp_false</ code > otherwise. When < code > L</ code > is empty, the result is < code > mp_false</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_for_each_l_f" > mp_for_each< L> (f)</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class L, class F> constexpr F mp_for_each(F&& f);</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_for_each< L> (f)</ code > calls < code > f</ code > with < code > T()</ code > for each element < code > T</ code > of the list < code > L</ code > , in order.</ p >
</ div >
< div class = "paragraph" >
< p > Returns < code > std::forward< F> (f)</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 59. Using mp_for_each and a C++14 lambda to print a tuple</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class... T> void print( std::tuple< T...> const & tp )
{
std::size_t const N = sizeof...(T);
2017-06-18 14:53:54 +03:00
mp_for_each< mp_iota_c< N>> ( [& ]( auto I ){
2017-06-10 03:44:31 +03:00
// I is mp_size_t< 0> , mp_size_t< 1> , ..., mp_size_t< N-1>
std::cout << std::get< I> (tp) << std::endl;
});
}</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect3" >
< h4 id = "mp_with_index_n_i_f" > mp_with_index< N> (i, f)</ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< std::size_t N, class F>
constexpr auto mp_with_index( std::size_t i, F && f )
-> decltype(std::declval< F> ()(std::declval< mp_size_t< 0>> ()));</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
2017-06-10 03:44:31 +03:00
< p >< code > mp_with_index< N> (i, f)</ code > calls < code > f</ code > with < code > mp_size_t< i> ()</ code > and returns the result. < code > i</ code > must be less than < code > N</ code > .
Only < code > constexpr</ code > on C++14 and higher.</ p >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class N, class F>
constexpr auto mp_with_index( std::size_t i, F && f )
-> decltype(std::declval< F> ()(std::declval< mp_size_t< 0>> ()));</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Returns < code > mp_with_index< N::value> (i, f)</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 60. Using mp_with_index and a C++14 lambda to print the active element of a variant</ div >
2017-06-10 03:44:31 +03:00
< div class = "content" >
< pre class = "highlight" >< code > template< class... T> void print( std::variant< T...> const& v )
{
mp_with_index< sizeof...(T)> ( v.index(), [& ]( auto I ) {
// I is mp_size_t< v.index()> here
std::cout << std::get< I> ( v ) << std::endl;
});
}</ code ></ pre >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "sect2" >
< h3 id = "set" > Set Operations, < boost/mp11/set.hpp> </ h3 >
< div class = "paragraph" >
< p > A set is a list whose elements are unique.</ p >
</ div >
< div class = "sect3" >
2017-07-17 19:28:36 +03:00
< h4 id = "mp_is_set_s" > mp_is_set< S> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class S> using mp_is_set = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_is_set< S> </ code > is < code > mp_true</ code > if < code > S</ code > is a set, < code > mp_false</ code > otherwise.</ p >
</ div >
</ div >
< div class = "sect3" >
2017-06-07 00:02:25 +03:00
< h4 id = "mp_set_contains_s_v" > mp_set_contains< S, V> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class S, class V> using mp_set_contains = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_set_contains< S, V> </ code > is < code > mp_true</ code > if the type < code > V</ code > is an element of the set < code > S</ code > , < code > mp_false</ code > otherwise.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_set_push_back_s_t" > mp_set_push_back< S, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class S, class... T> using mp_set_push_back = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > For each < code > T1</ code > in < code > T…​ </ code > , < code > mp_set_push_back< S, T…​> </ code > appends < code > T1</ code > to the end of < code > S</ code > if it’ s not already an element of < code > S</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_set_push_front_s_t" > mp_set_push_front< S, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class S, class... T> using mp_set_push_front = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_set_push_front< S, T…​> </ code > inserts at the front of < code > S</ code > those elements of < code > T…​ </ code > for which < code > S</ code > does not already contain the same type.</ p >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "map" > Map Operations, < boost/mp11/map.hpp> </ h3 >
< div class = "paragraph" >
< p > A map is a list of lists, the inner lists having at least one element (the key.) The keys of the map must be unique.</ p >
</ div >
< div class = "sect3" >
2017-07-17 20:14:43 +03:00
< h4 id = "mp_is_map_m" > mp_is_map< M> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M> using mp_is_map = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_is_map< M> </ code > is < code > mp_true</ code > if < code > M</ code > is a map, < code > mp_false</ code > otherwise.</ p >
</ div >
</ div >
< div class = "sect3" >
2017-06-07 00:02:25 +03:00
< h4 id = "mp_map_find_m_k" > mp_map_find< M, K> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M, class K> using mp_map_find = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_map_find< M, K> </ code > is an alias for the element of the map < code > M</ code > with a key < code > K</ code > , or for < code > void</ code > , if there is no such element.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_map_contains_m_k" > mp_map_contains< M, K> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class M, class K> using mp_map_contains =
mp_not< std::is_same< mp_map_find< M, K> , void>> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_map_contains< M, K> </ code > is < code > mp_true</ code > if the map < code > M</ code > contains an element with a key < code > K</ code > , < code > mp_false</ code > otherwise.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_map_insert_m_t" > mp_map_insert< M, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-09 20:35:21 +03:00
< pre > template< class M, class T> using mp_map_insert =
mp_if< mp_map_contains< M, mp_first< T>> , M, mp_push_back< M, T> > ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > Inserts the element < code > T</ code > into the map < code > M</ code > , if an element with a key < code > mp_first< T> </ code > is not already in < code > M</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_map_replace_m_t" > mp_map_replace< M, T> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M, class T> using mp_map_replace = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > If the map < code > M</ code > does not contain an element with a key < code > mp_first< T> </ code > , inserts it (using < code > mp_push_back< M, T> </ code > ); otherwise,
replaces the existing element with < code > T</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_map_update_m_t_f" > mp_map_update< M, T, F> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M, class T, template< class...> class F> using mp_map_update = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > If the map < code > M</ code > does not contain an element with a key < code > mp_first< T> </ code > , inserts it (using < code > mp_push_back< M, T> </ code > ); otherwise,
replaces the existing element < code > L< X, Y…​> </ code > with < code > L< X, F< X, Y…​>> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_map_erase_m_k" > mp_map_erase< M, K> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M, class K> using mp_map_erase = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > If the map < code > M</ code > contains an element with a key < code > K</ code > , removes it.</ p >
</ div >
</ div >
2017-07-17 19:46:51 +03:00
< div class = "sect3" >
< h4 id = "mp_map_keys_m" > mp_map_keys< M> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class M> using mp_map_keys = mp_transform< mp_first, M> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_map_keys< M> </ code > returns a list of the keys of < code > M</ code > . When < code > M</ code > is a valid map, the keys are unique, so the result is a set.</ p >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
< div class = "sect2" >
< h3 id = "function" > Helper Metafunctions, < boost/mp11/function.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "mp_void_t" > mp_void< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_void = void;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > Same as < code > std::void_t</ code > from C++17.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_and_t" > mp_and< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_and = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_and< T…​> </ code > applies < code > mp_to_bool</ code > to the types in < code > T…​ </ code > , in order. If the result of an application is < code > mp_false</ code > , < code > mp_and</ code >
returns < code > mp_false</ code > . If the application causes a substitution failure, returns < code > mp_false</ code > . If all results are < code > mp_true</ code > ,
returns < code > mp_true</ code > . < code > mp_and<> </ code > is < code > mp_true</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 61. mp_and behavior</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using R1 = mp_and< mp_true, mp_true> ; // mp_true
using R2 = mp_and< mp_false, void> ; // mp_false, void is not reached
using R3 = mp_and< mp_false, mp_false> ; // mp_false
using R4 = mp_and< void, mp_true> ; // mp_false (!)</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_all_t" > mp_all< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_all = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_all< T…​> </ code > is < code > mp_true</ code > if < code > mp_to_bool< U> </ code > is < code > mp_true</ code > for all types < code > U</ code > in < code > T…​ </ code > , < code > mp_false</ code > otherwise. Same as
< code > mp_and</ code > , but does not perform short-circuit evaluation. < code > mp_and< mp_false, void> </ code > is < code > mp_false</ code > , but < code > mp_all< mp_false, void> </ code >
is an error because < code > void</ code > does not have a nested < code > value</ code > . The upside is that < code > mp_all</ code > is potentially faster and does not
mask substitution failures as < code > mp_and</ code > does.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 62. mp_all behavior</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using R1 = mp_all< mp_true, mp_true> ; // mp_true
using R2 = mp_all< mp_false, void> ; // compile-time error
using R3 = mp_all< mp_false, mp_false> ; // mp_false
using R4 = mp_all< void, mp_true> ; // compile-time error</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_or_t" > mp_or< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_or = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_or< T…​> </ code > applies < code > mp_to_bool</ code > to the types in < code > T…​ </ code > , in order. If the result of an application is < code > mp_true</ code > , < code > mp_or</ code >
returns < code > mp_true</ code > . If all results are < code > mp_false</ code > , returns < code > mp_false</ code > . < code > mp_or<> </ code > is < code > mp_false</ code > .</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 63. mp_or behavior</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using R1 = mp_or< mp_true, mp_false> ; // mp_true
using R2 = mp_or< mp_true, void> ; // mp_true, void is not reached
using R3 = mp_or< mp_false, mp_false> ; // mp_false
using R4 = mp_or< void, mp_true> ; // compile-time error</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_any_t" > mp_any< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_any = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_any< T…​> </ code > is < code > mp_true</ code > if < code > mp_to_bool< U> </ code > is < code > mp_true</ code > for any type < code > U</ code > in < code > T…​ </ code > , < code > mp_false</ code > otherwise. Same as
< code > mp_or</ code > , but does not perform short-circuit evaluation.</ p >
</ div >
2017-06-10 03:44:31 +03:00
< div class = "listingblock" >
2017-06-26 16:15:43 +03:00
< div class = "title" > Code Example 64. mp_any behavior</ div >
2017-06-07 00:02:25 +03:00
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre class = "highlight" >< code > using R1 = mp_any< mp_true, mp_false> ; // mp_true
using R2 = mp_any< mp_true, void> ; // compile-time error
using R3 = mp_any< mp_false, mp_false> ; // mp_false
using R4 = mp_any< void, mp_true> ; // compile-time error</ code ></ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_same_t" > mp_same< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_same = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_same< T…​> </ code > is < code > mp_true</ code > if all the types in < code > T…​ </ code > are the same type, < code > mp_false</ code > otherwise. < code > mp_same<> </ code > is < code > mp_true</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_plus_t" > mp_plus< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class... T> using mp_plus = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_plus< T…​> </ code > is an integral constant type with a value that is the sum of < code > U::value</ code > for all types < code > U</ code > in < code > T…​ </ code > .
< code > mp_plus<> </ code > is < code > mp_int< 0> </ code > .</ p >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "bind" > Bind, < boost/mp11/bind.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "mp_arg_i" > mp_arg< I> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< std::size_t I> struct mp_arg;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_arg< I> </ code > is a quoted metafunction whose nested template < code > fn< T…​> </ code > returns the < code > I</ code > -th zero-based element of < code > T…​ </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "1_9" > _1, …​ , _9</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > using _1 = mp_arg< 0> ;
using _2 = mp_arg< 1> ;
using _3 = mp_arg< 2> ;
using _4 = mp_arg< 3> ;
using _5 = mp_arg< 4> ;
using _6 = mp_arg< 5> ;
using _7 = mp_arg< 6> ;
using _8 = mp_arg< 7> ;
using _9 = mp_arg< 8> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > _1</ code > to < code > _9</ code > are placeholder types, the equivalent to the placeholders of < code > boost::bind</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_f_t" > mp_bind< F, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... T> struct mp_bind;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_bind< F, T…​> </ code > is a quoted metafunction that implements the type-based equivalent of < code > boost::bind</ code > . Its nested
template < code > fn< U…​> </ code > returns < code > F< V…​> </ code > , where < code > V…​ </ code > is < code > T…​ </ code > with the placeholders replaced by the corresponding element
of < code > U…​ </ code > and the < code > mp_bind</ code > expressions replaced with their corresponding evaluations against < code > U…​ </ code > .</ p >
</ div >
< div class = "paragraph" >
< p > For example, < code > mp_bind< F, int, _2, mp_bind< G, _1>> ::fn< float, void> </ code > is < code > F< int, void, G< float>> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_q_q_t" > mp_bind_q< Q, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class Q, class... T> using mp_bind_q = mp_bind< Q::template fn, T...> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p > As < code > mp_bind</ code > , but takes a quoted metafunction.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_front_f_t" > mp_bind_front< F, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... T> struct mp_bind_front;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_bind_front< F, T…​> </ code > binds the leftmost arguments of < code > F</ code > to < code > T…​ </ code > . Its nested template < code > fn< U…​> </ code > returns < code > F< T…​ , U…​> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_front_q_q_t" > mp_bind_front_q< Q, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class Q, class... T> using mp_bind_front_q =
mp_bind_front< Q::template fn, T...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > As < code > mp_bind_front</ code > , but takes a quoted metafunction.</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_back_f_t" > mp_bind_back< F, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< template< class...> class F, class... T> struct mp_bind_back;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > mp_bind_back< F, T…​> </ code > binds the rightmost arguments of < code > F</ code > to < code > T…​ </ code > . Its nested template < code > fn< U…​> </ code > returns < code > F< U…​ , T…​> </ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "mp_bind_back_q_q_t" > mp_bind_back_q< Q, T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class Q, class... T> using mp_bind_back_q =
mp_bind_back< Q::template fn, T...> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p > As < code > mp_bind_back</ code > , but takes a quoted metafunction.</ p >
</ div >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "integer_sequence" > Integer Sequences, < boost/mp11/integer_sequence.hpp> </ h3 >
< div class = "sect3" >
< h4 id = "integer_sequence_t_i" > integer_sequence< T, I…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T, T... I> struct integer_sequence
{
};</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > integer_sequence< T, I…​> </ code > holds a sequence of integers of type < code > T</ code > . Same as C++14’ s < code > std::integer_sequence</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "make_integer_sequence_t_n" > make_integer_sequence< T, N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class T, T N> using make_integer_sequence = /*...*/;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > make_integer_sequence< T, N> </ code > is < code > integer_sequence< T, 0, 1, …​ , N-1> </ code > . Same as C++14’ s < code > std::make_integer_sequence</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "index_sequence_i" > index_sequence< I…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< std::size_t... I> using index_sequence = integer_sequence< std::size_t, I...> ;</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > index_sequence< I…​> </ code > is an alias for < code > integer_sequence< size_t, I…​> </ code > . Same as C++14’ s < code > std::index_sequence</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "make_index_sequence_n" > make_index_sequence< N> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< std::size_t N> using make_index_sequence =
make_integer_sequence< std::size_t, N> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > make_index_sequence< N> </ code > is < code > index_sequence< 0, 1, …​ , N-1> </ code > . Same as C++14’ s < code > std::make_index_sequence</ code > .</ p >
</ div >
</ div >
< div class = "sect3" >
< h4 id = "index_sequence_for_t" > index_sequence_for< T…​> </ h4 >
< div class = "literalblock" >
< div class = "content" >
2017-06-10 03:44:31 +03:00
< pre > template< class... T> using index_sequence_for =
make_integer_sequence< std::size_t, sizeof...(T)> ;</ pre >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "paragraph" >
< p >< code > index_sequence_for< N> </ code > is < code > make_index_sequence< sizeof…​ (T)> </ code > . Same as C++14’ s < code > std::index_sequence_for</ code > .</ p >
</ div >
</ div >
</ div >
< div class = "sect2" >
2017-06-08 16:35:55 +03:00
< h3 id = "tuple" > Tuple Operations, < boost/mp11/tuple.hpp> </ h3 >
2017-06-07 00:02:25 +03:00
< div class = "sect3" >
2017-06-08 17:19:28 +03:00
< h4 id = "tuple_apply_f_tp" > tuple_apply(f, tp)</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class F, class Tp> constexpr /*...*/ tuple_apply(F&& f, Tp&& tp);</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > tuple_apply(f, tp)</ code > returns < code > std::forward< F> (f)(std::get< J> (std::forward< Tp> (tp))…​ )</ code > for < code > J</ code > in 0..< code > N-1</ code > ,
where < code > N</ code > is < code > std::tuple_size< typename std::remove_reference< Tp> ::type> ::value</ code > . Same as < code > std::apply</ code > in C++17.</ p >
</ div >
</ div >
< div class = "sect3" >
2017-06-08 19:22:53 +03:00
< h4 id = "construct_from_tuple_t_tp" > construct_from_tuple< T> (tp)</ h4 >
2017-06-08 17:42:50 +03:00
< div class = "literalblock" >
< div class = "content" >
2017-06-08 19:22:53 +03:00
< pre > template< class T, class Tp> T construct_from_tuple(Tp&& tp);</ pre >
2017-06-08 17:42:50 +03:00
</ div >
</ div >
< div class = "paragraph" >
2017-06-08 19:22:53 +03:00
< p >< code > construct_from_tuple< T> (tp)</ code > returns < code > T(std::get< J> (std::forward< Tp> (tp))…​ )</ code > for < code > J</ code > in 0..< code > N-1</ code > ,
where < code > N</ code > is < code > std::tuple_size< typename std::remove_reference< Tp> ::type> ::value</ code > . Same as < code > std::make_from_tuple</ code > in C++17.
The name of the function doesn’ t match the C++17 one to avoid ambiguities when both are visible or in unqualified calls.</ p >
2017-06-08 17:42:50 +03:00
</ div >
</ div >
< div class = "sect3" >
2017-06-07 00:02:25 +03:00
< h4 id = "tuple_for_each_tp_f" > tuple_for_each(tp, f)</ h4 >
< div class = "literalblock" >
< div class = "content" >
< pre > template< class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);</ pre >
</ div >
</ div >
< div class = "paragraph" >
< p >< code > tuple_for_each(tp, f)</ code > applies the function object < code > f</ code > to each element of < code > tp</ code > by evaluating the
expression < code > f(std::get< J> (std::forward< Tp> (tp)))</ code > for < code > J</ code > in 0..< code > N-1</ code > , where < code > N</ code > is < code > std::tuple_size< typename std::remove_reference< Tp> ::type> ::value</ code > .</ p >
</ div >
< div class = "paragraph" >
< p > Returns < code > std::forward< F> (f)</ code > .</ p >
</ div >
</ div >
</ div >
2017-07-20 21:05:31 +03:00
< div class = "sect2" >
< h3 id = "mp11" > Convenience Header, < boost/mp11.hpp> </ h3 >
< div class = "paragraph" >
< p > The convenience header < code > < boost/mp11.hpp> </ code > includes all of the
headers listed previously in this reference.</ p >
</ div >
</ div >
< div class = "sect2" >
< h3 id = "mpl" > MPL Support, < boost/mp11/mpl.hpp> </ h3 >
< div class = "paragraph" >
< p > The header < code > < boost/mp11/mpl.hpp> </ code > , when included, defines the
necessary support infrastructure for < code > mp_list</ code > and < code > std::tuple</ code >
to be valid < a href = "../../../../libs/mpl" > MPL</ a > sequences.</ p >
</ div >
< div class = "admonitionblock note" >
< table >
< tr >
< td class = "icon" >
< div class = "title" > Note</ div >
</ td >
< td class = "content" >
< code > mpl.hpp</ code > is not included by < code > < boost/mp11.hpp> </ code > .
</ td >
</ tr >
</ table >
</ div >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
< div class = "sect1" >
< h2 id = "copyright_and_license" > Appendix A: Copyright and License</ h2 >
< div class = "sectionbody" >
< div class = "paragraph" >
< p > This documentation is</ p >
</ div >
< div class = "ulist" >
< ul >
< li >
< p > Copyright 2017 Peter Dimov</ p >
</ li >
< li >
2017-06-17 19:44:32 +03:00
< p > Copyright 2017 Bjørn Reese</ p >
2017-06-07 00:02:25 +03:00
</ li >
</ ul >
</ div >
2017-06-17 19:44:32 +03:00
< div class = "paragraph" >
< p > and is distributed under the < a href = "http://www.boost.org/LICENSE_1_0.txt" > Boost Software License, Version 1.0</ a > .</ p >
</ div >
2017-06-07 00:02:25 +03:00
</ div >
</ div >
</ div >
< div id = "footer" >
< div id = "footer-text" >
2017-06-18 14:53:54 +03:00
Last updated 2017-06-18 02:23:06 GTBDT
2017-06-07 00:02:25 +03:00
</ div >
</ div >
2017-06-11 04:35:34 +03:00
< style >
* : not ( pre )> code { background : none ; color : #600000 ; }
table tr . even , table tr . alt , table tr : nth-of-type ( even ) { background : none ; }
</ style >
2017-03-14 22:57:07 +02:00
</ body >
2017-06-07 00:02:25 +03:00
</ html >