1[/============================================================================== 2 Copyright (C) 2001-2011 Joel de Guzman 3 Copyright (C) 2006 Dan Marsden 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8===============================================================================/] 9[section Support] 10 11A couple of classes and metafunctions provide basic support for Fusion. 12 13[section is_sequence] 14 15[heading Description] 16 17Metafunction that evaluates to `mpl::true_` if a certain type `T` is a 18conforming Fusion __sequence__, `mpl::false_` otherwise. This may be 19specialized to accommodate clients which provide Fusion conforming sequences. 20 21[heading Synopsis] 22 23 namespace traits 24 { 25 template <typename T> 26 struct is_sequence 27 { 28 typedef __unspecified__ type; 29 }; 30 } 31 32[heading Parameters] 33 34[table 35 [[Parameter] [Requirement] [Description]] 36 [[`T`] [Any type] [The type to query.]] 37] 38 39[heading Expression Semantics] 40 41 typedef traits::is_sequence<T>::type c; 42 43[*Return type]: An __mpl_boolean_constant__. 44 45[*Semantics]: Metafunction that evaluates to `mpl::true_` if a certain type 46`T` is a conforming Fusion sequence, `mpl::false_` otherwise. 47 48[heading Header] 49 50 #include <boost/fusion/support/is_sequence.hpp> 51 #include <boost/fusion/include/is_sequence.hpp> 52 53[heading Example] 54 55 BOOST_MPL_ASSERT_NOT(( traits::is_sequence< std::vector<int> > )); 56 BOOST_MPL_ASSERT_NOT(( is_sequence< int > )); 57 BOOST_MPL_ASSERT(( traits::is_sequence<__list__<> > )); 58 BOOST_MPL_ASSERT(( traits::is_sequence<__list__<int> > )); 59 BOOST_MPL_ASSERT(( traits::is_sequence<__vector__<> > )); 60 BOOST_MPL_ASSERT(( traits::is_sequence<__vector__<int> > )); 61 62[endsect] 63 64[section is_view] 65 66[heading Description] 67 68Metafunction that evaluates to `mpl::true_` if a certain type `T` is a 69conforming Fusion __view__, `mpl::false_` otherwise. A view is a 70specialized sequence that does not actually contain data. Views hold 71sequences which may be other views. In general, views are held by other 72views by value, while non-views are held by other views by reference. `is_view` 73may be specialized to accommodate clients providing Fusion conforming views. 74 75[heading Synopsis] 76 77 namespace traits 78 { 79 template <typename T> 80 struct is_view 81 { 82 typedef __unspecified__ type; 83 }; 84 } 85 86[heading Parameters] 87 88[table 89 [[Parameter] [Requirement] [Description]] 90 [[`T`] [Any type] [The type to query.]] 91] 92 93[heading Expression Semantics] 94 95 typedef traits::is_view<T>::type c; 96 97[*Return type]: An __mpl_boolean_constant__. 98 99[*Semantics]: Metafunction that evaluates to `mpl::true_` if a certain type 100`T` is a conforming Fusion view, `mpl::false_` otherwise. 101 102[heading Header] 103 104 #include <boost/fusion/support/is_view.hpp> 105 #include <boost/fusion/include/is_view.hpp> 106 107[heading Example] 108 109 BOOST_MPL_ASSERT_NOT(( traits::is_view<std::vector<int> > )); 110 BOOST_MPL_ASSERT_NOT(( traits::is_view<int> )); 111 112 using boost::mpl::_ 113 using boost::is_pointer; 114 typedef __vector__<int*, char, long*, bool, double> vector_type; 115 typedef __filter_view__<vector_type, is_pointer<_> > filter_view_type; 116 BOOST_MPL_ASSERT(( traits::is_view<filter_view_type> )); 117 118[endsect] 119 120[section tag_of] 121 122[heading Description] 123 124All conforming Fusion sequences and iterators have an associated tag type. The 125purpose of the tag is to enable __tag_dispatching__ from __intrinsic__ 126functions to implementations appropriate for the type. 127 128This metafunction may be specialized to accommodate clients providing Fusion 129conforming sequences. 130 131[heading Synopsis] 132 133 namespace traits 134 { 135 template<typename Sequence> 136 struct tag_of 137 { 138 typedef __unspecified__ type; 139 }; 140 } 141 142[heading Parameters] 143 144[table 145 [[Parameter] [Requirement] [Description]] 146 [[`T`] [Any type] [The type to query.]] 147] 148 149[heading Expression Semantics] 150 151 typedef traits::tag_of<T>::type tag; 152 153[*Return type]: Any type. 154 155[*Semantics]: Returns the tag type associated with `T`. 156 157[heading Header] 158 159 #include <boost/fusion/support/tag_of.hpp> 160 #include <boost/fusion/include/tag_of.hpp> 161 162[heading Example] 163 164 typedef traits::tag_of<__list__<> >::type tag1; 165 typedef traits::tag_of<__list__<int> >::type tag2; 166 typedef traits::tag_of<__vector__<> >::type tag3; 167 typedef traits::tag_of<__vector__<int> >::type tag4; 168 169 BOOST_MPL_ASSERT((boost::is_same<tag1, tag2>)); 170 BOOST_MPL_ASSERT((boost::is_same<tag3, tag4>)); 171 172[endsect] 173 174[section category_of] 175 176[heading Description] 177 178A metafunction that establishes the conceptual classification of a particular 179__sequence__ or __iterator__ (see __iterator_concepts__ and 180__sequence_concepts__). 181 182[heading Synopsis] 183 184 namespace traits 185 { 186 template <typename T> 187 struct category_of 188 { 189 typedef __unspecified__ type; 190 }; 191 } 192 193[heading Parameters] 194 195[table 196 [[Parameter] [Requirement] [Description]] 197 [[`T`] [Any type] [The type to query.]] 198] 199 200[heading Expression Semantics] 201 202 typedef traits::category_of<T>::type category; 203 204[*Return type]: 205 206The return type is derived from one of: 207 208 namespace boost { namespace fusion 209 { 210 struct incrementable_traversal_tag {}; 211 212 struct single_pass_traversal_tag 213 : incrementable_traversal_tag {}; 214 215 struct forward_traversal_tag 216 : single_pass_traversal_tag {}; 217 218 struct bidirectional_traversal_tag 219 : forward_traversal_tag {}; 220 221 struct random_access_traversal_tag 222 : bidirectional_traversal_tag {}; 223 }} 224 225And optionally from: 226 227 namespace boost { namespace fusion 228 { 229 struct associative_tag {}; 230 231 struct unbounded_tag {}; 232 }} 233 234[*Semantics]: Establishes the conceptual classification of a particular 235__sequence__ or __iterator__. 236 237[heading Header] 238 239 #include <boost/fusion/support/category_of.hpp> 240 #include <boost/fusion/include/category_of.hpp> 241 242[heading Example] 243 244 using boost::is_base_of; 245 typedef traits::category_of<__list__<> >::type list_category; 246 typedef traits::category_of<__vector__<> >::type vector_category; 247 BOOST_MPL_ASSERT(( is_base_of<forward_traversal_tag, list_category> )); 248 BOOST_MPL_ASSERT(( is_base_of<random_access_traversal_tag, vector_category> )); 249 250[endsect] 251 252[section deduce] 253 254[heading Description] 255Metafunction to apply __element_conversion__ to the full argument type. 256 257It removes references to `const`, references to array types are kept, even 258if the array is `const`. Reference wrappers are removed (see 259__note_ref_wrappers__)[footnote Since C++11, the standard reference wrappers 260are also removed.]. 261 262[heading Header] 263 264 #include <boost/fusion/support/deduce.hpp> 265 #include <boost/fusion/include/deduce.hpp> 266 267[heading Synopsis] 268 namespace traits 269 { 270 template <typename T> 271 struct deduce 272 { 273 typedef __unspecified__ type; 274 }; 275 } 276 277[heading Example] 278 template <typename T> 279 struct holder 280 { 281 typename traits::deduce<T const &>::type element; 282 283 holder(T const & a) 284 : element(a) 285 { } 286 }; 287 288 template <typename T> 289 holder<T> make_holder(T const & a) 290 { 291 return holder<T>(a); 292 } 293 294[heading See also] 295* __deduce_sequence__ 296 297[endsect] 298 299[section deduce_sequence] 300 301[heading Description] 302Applies __element_conversion__ to each element in a __forward_sequence__. 303The resulting type is a __random_access_sequence__ that provides a converting 304constructor accepting the original type as its argument. 305 306[heading Header] 307 308 #include <boost/fusion/support/deduce_sequence.hpp> 309 #include <boost/fusion/include/deduce_sequence.hpp> 310 311[heading Synopsis] 312 namespace traits 313 { 314 template <class Sequence> 315 struct deduce_sequence 316 { 317 typedef __unspecified__ type; 318 }; 319 } 320 321[heading Example] 322 template <class Seq> 323 struct holder 324 { 325 typename traits::deduce_sequence<Seq>::type element; 326 327 holder(Seq const & a) 328 : element(a) 329 { } 330 }; 331 332 template <typename T0, typename T1> 333 holder< __vector__<T0 const &, T1 const &> > 334 make_holder(T0 const & a0, T1 const & a1) 335 { 336 typedef __vector__<T0 const &, T1 const &> arg_vec_t; 337 return holder<arg_vec_t>( arg_vec_t(a0,a1) ); 338 } 339 340[heading See also] 341* __deduce__ 342 343[endsect] 344 345[section pair] 346 347[heading Description] 348 349Fusion `pair` type is a half runtime pair. A half runtime pair is similar 350to a __std_pair__, but, unlike __std_pair__, the first type does not have data. 351It is used as elements in __map__\ s, for example. 352 353[heading Synopsis] 354 355 template <typename First, typename Second> 356 struct pair; 357 358 namespace result_of 359 { 360 template <typename Pair> 361 struct first; 362 363 template <typename Pair> 364 struct second; 365 366 template <typename First, typename Second> 367 struct make_pair; 368 } 369 370 template <typename First, typename Second> 371 typename result_of::make_pair<First,Second>::type 372 make_pair(Second const &); 373 374[heading Template parameters] 375 376[table 377 [[Parameter] [Description]] 378 [[First] [The first type. This is purely a type. No data is held.]] 379 [[Second] [The second type. This contains data.]] 380] 381 382[variablelist Notation 383 [[`P`] [Fusion pair type]] 384 [[`p`, `p2`] [Fusion pairs]] 385 [[`F`, `S`] [Arbitrary types]] 386 [[`s`] [Value of type `S`]] 387 [[`o`] [Output stream]] 388 [[`i`] [Input stream]] 389] 390 391[heading Expression Semantics] 392 393[table 394 [[Expression] [Semantics]] 395 [[`P::first_type`] [The type of the first template parameter, `F`, equivalent to 396 `result_of::first<P>::type`. ]] 397 [[`P::second_type`] [The type of the second template parameter, `S`, equivalent to 398 `result_of::second<P>::type`. ]] 399 [[`P()`] [Default construction.]] 400 [[`P(s)`] [Construct a pair given value for the second type, `s`.]] 401 [[`P(p2)`] [Copy constructs a pair from another pair, `p2`.]] 402 [[`p.second`] [Get the data from `p1`.]] 403 [[`p = p2`] [Assigns a pair, `p1`, from another pair, `p2`.]] 404 [[make_pair<F>(s)] [Make a pair given the first type, `F`, and a value for 405 the second type, `s`. The second type assumes the type of `s`]] 406 [[`o << p`] [Output `p` to output stream, `o`.]] 407 [[`i >> p`] [Input `p` from input stream, `i`.]] 408 [[`p == p2`] [Tests two pairs for equality.]] 409 [[`p != p2`] [Tests two pairs for inequality.]] 410] 411 412[heading Header] 413 414 #include <boost/fusion/support/pair.hpp> 415 #include <boost/fusion/include/pair.hpp> 416 417[heading Example] 418 419 pair<int, char> p('X'); 420 std::cout << p << std::endl; 421 std::cout << make_pair<int>('X') << std::endl; 422 assert((p == make_pair<int>('X'))); 423 424[endsect] 425 426[endsect] 427 428