annotate DEPENDENCIES/generic/include/boost/spirit/home/support/container.hpp @ 91:e2e7672ea759

Some absolute paths
author Chris Cannam
date Tue, 14 Apr 2015 11:32:55 +0100
parents 2665513ce2d3
children c530137014c0
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2001-2011 Joel de Guzman
Chris@16 3 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 4 http://spirit.sourceforge.net/
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM)
Chris@16 10 #define BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM
Chris@16 11
Chris@16 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/spirit/home/support/unused.hpp>
Chris@16 17 #include <boost/spirit/home/support/attributes_fwd.hpp>
Chris@16 18 #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
Chris@16 19 #include <boost/mpl/has_xxx.hpp>
Chris@16 20 #include <boost/mpl/bool.hpp>
Chris@16 21 #include <boost/optional.hpp>
Chris@16 22 #include <boost/variant.hpp>
Chris@16 23 #include <boost/preprocessor/cat.hpp>
Chris@16 24 #include <boost/preprocessor/repeat.hpp>
Chris@16 25 #include <boost/range/iterator_range.hpp>
Chris@16 26
Chris@16 27 namespace boost { namespace spirit { namespace traits
Chris@16 28 {
Chris@16 29 ///////////////////////////////////////////////////////////////////////////
Chris@16 30 // This file contains some container utils for stl containers. The
Chris@16 31 // utilities provided also accept spirit's unused_type; all no-ops.
Chris@16 32 // Compiler optimization will easily strip these away.
Chris@16 33 ///////////////////////////////////////////////////////////////////////////
Chris@16 34
Chris@16 35 namespace detail
Chris@16 36 {
Chris@16 37 BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
Chris@16 38 BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
Chris@16 39 BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
Chris@16 40 BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
Chris@16 41 }
Chris@16 42
Chris@16 43 template <typename T, typename Enable/* = void*/>
Chris@16 44 struct is_container
Chris@16 45 : mpl::bool_<
Chris@16 46 detail::has_value_type<T>::value &&
Chris@16 47 detail::has_iterator<T>::value &&
Chris@16 48 detail::has_size_type<T>::value &&
Chris@16 49 detail::has_reference<T>::value>
Chris@16 50 {};
Chris@16 51
Chris@16 52 template <typename T>
Chris@16 53 struct is_container<T&>
Chris@16 54 : is_container<T>
Chris@16 55 {};
Chris@16 56
Chris@16 57 template <typename T>
Chris@16 58 struct is_container<boost::optional<T> >
Chris@16 59 : is_container<T>
Chris@16 60 {};
Chris@16 61
Chris@16 62 #define BOOST_SPIRIT_IS_CONTAINER(z, N, data) \
Chris@16 63 is_container<BOOST_PP_CAT(T, N)>::value || \
Chris@16 64 /***/
Chris@16 65
Chris@16 66 // make sure unused variant parameters do not affect the outcome
Chris@16 67 template <>
Chris@16 68 struct is_container<boost::detail::variant::void_>
Chris@16 69 : mpl::false_
Chris@16 70 {};
Chris@16 71
Chris@16 72 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@16 73 struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@16 74 : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
Chris@16 75 , BOOST_SPIRIT_IS_CONTAINER, _) false>
Chris@16 76 {};
Chris@16 77
Chris@16 78 #undef BOOST_SPIRIT_IS_CONTAINER
Chris@16 79
Chris@16 80 template <typename T, typename Enable/* = void*/>
Chris@16 81 struct is_iterator_range
Chris@16 82 : mpl::false_
Chris@16 83 {};
Chris@16 84
Chris@16 85 template <typename T>
Chris@16 86 struct is_iterator_range<iterator_range<T> >
Chris@16 87 : mpl::true_
Chris@16 88 {};
Chris@16 89
Chris@16 90 ///////////////////////////////////////////////////////////////////////////
Chris@16 91 namespace detail
Chris@16 92 {
Chris@16 93 template <typename T>
Chris@16 94 struct remove_value_const
Chris@16 95 {
Chris@16 96 typedef T type;
Chris@16 97 };
Chris@16 98
Chris@16 99 template <typename T>
Chris@16 100 struct remove_value_const<T const>
Chris@16 101 : remove_value_const<T>
Chris@16 102 {};
Chris@16 103
Chris@16 104 template <typename F, typename S>
Chris@16 105 struct remove_value_const<std::pair<F, S> >
Chris@16 106 {
Chris@16 107 typedef typename remove_value_const<F>::type first_type;
Chris@16 108 typedef typename remove_value_const<S>::type second_type;
Chris@16 109 typedef std::pair<first_type, second_type> type;
Chris@16 110 };
Chris@16 111 }
Chris@16 112
Chris@16 113 ///////////////////////////////////////////////////////////////////////
Chris@16 114 //[customization_container_value_default
Chris@16 115 template <typename Container, typename Enable/* = void*/>
Chris@16 116 struct container_value
Chris@16 117 : detail::remove_value_const<typename Container::value_type>
Chris@16 118 {};
Chris@16 119 //]
Chris@16 120
Chris@16 121 template <typename T>
Chris@16 122 struct container_value<T&>
Chris@16 123 : container_value<T>
Chris@16 124 {};
Chris@16 125
Chris@16 126 // this will be instantiated if the optional holds a container
Chris@16 127 template <typename T>
Chris@16 128 struct container_value<boost::optional<T> >
Chris@16 129 : container_value<T>
Chris@16 130 {};
Chris@16 131
Chris@16 132 // this will be instantiated if the variant holds a container
Chris@16 133 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@16 134 struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@16 135 {
Chris@16 136 typedef typename
Chris@16 137 variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
Chris@16 138 types;
Chris@16 139 typedef typename
Chris@16 140 mpl::find_if<types, is_container<mpl::_1> >::type
Chris@16 141 iter;
Chris@16 142
Chris@16 143 typedef typename container_value<
Chris@16 144 typename mpl::if_<
Chris@16 145 is_same<iter, typename mpl::end<types>::type>
Chris@16 146 , unused_type, typename mpl::deref<iter>::type
Chris@16 147 >::type
Chris@16 148 >::type type;
Chris@16 149 };
Chris@16 150
Chris@16 151 //[customization_container_value_unused
Chris@16 152 template <>
Chris@16 153 struct container_value<unused_type>
Chris@16 154 {
Chris@16 155 typedef unused_type type;
Chris@16 156 };
Chris@16 157 //]
Chris@16 158
Chris@16 159 template <>
Chris@16 160 struct container_value<unused_type const>
Chris@16 161 {
Chris@16 162 typedef unused_type type;
Chris@16 163 };
Chris@16 164
Chris@16 165 ///////////////////////////////////////////////////////////////////////////
Chris@16 166 template <typename Container, typename Enable/* = void*/>
Chris@16 167 struct container_iterator
Chris@16 168 {
Chris@16 169 typedef typename Container::iterator type;
Chris@16 170 };
Chris@16 171
Chris@16 172 template <typename Container>
Chris@16 173 struct container_iterator<Container&>
Chris@16 174 : container_iterator<Container>
Chris@16 175 {};
Chris@16 176
Chris@16 177 template <typename Container>
Chris@16 178 struct container_iterator<Container const>
Chris@16 179 {
Chris@16 180 typedef typename Container::const_iterator type;
Chris@16 181 };
Chris@16 182
Chris@16 183 template <typename T>
Chris@16 184 struct container_iterator<optional<T> >
Chris@16 185 : container_iterator<T>
Chris@16 186 {};
Chris@16 187
Chris@16 188 template <typename T>
Chris@16 189 struct container_iterator<optional<T> const>
Chris@16 190 : container_iterator<T const>
Chris@16 191 {};
Chris@16 192
Chris@16 193 template <typename Iterator>
Chris@16 194 struct container_iterator<iterator_range<Iterator> >
Chris@16 195 {
Chris@16 196 typedef typename range_const_iterator<
Chris@16 197 iterator_range<Iterator> >::type type;
Chris@16 198 };
Chris@16 199
Chris@16 200 template <>
Chris@16 201 struct container_iterator<unused_type>
Chris@16 202 {
Chris@16 203 typedef unused_type const* type;
Chris@16 204 };
Chris@16 205
Chris@16 206 template <>
Chris@16 207 struct container_iterator<unused_type const>
Chris@16 208 {
Chris@16 209 typedef unused_type const* type;
Chris@16 210 };
Chris@16 211
Chris@16 212 ///////////////////////////////////////////////////////////////////////////
Chris@16 213 template <typename T, typename Enable/* = void*/>
Chris@16 214 struct optional_attribute
Chris@16 215 {
Chris@16 216 typedef T const& type;
Chris@16 217
Chris@16 218 static type call(T const& val)
Chris@16 219 {
Chris@16 220 return val;
Chris@16 221 }
Chris@16 222
Chris@16 223 static bool is_valid(T const&)
Chris@16 224 {
Chris@16 225 return true;
Chris@16 226 }
Chris@16 227 };
Chris@16 228
Chris@16 229 template <typename T>
Chris@16 230 struct optional_attribute<boost::optional<T> >
Chris@16 231 {
Chris@16 232 typedef T const& type;
Chris@16 233
Chris@16 234 static type call(boost::optional<T> const& val)
Chris@16 235 {
Chris@16 236 return boost::get<T>(val);
Chris@16 237 }
Chris@16 238
Chris@16 239 static bool is_valid(boost::optional<T> const& val)
Chris@16 240 {
Chris@16 241 return val;
Chris@16 242 }
Chris@16 243 };
Chris@16 244
Chris@16 245 template <typename T>
Chris@16 246 typename optional_attribute<T>::type
Chris@16 247 optional_value(T const& val)
Chris@16 248 {
Chris@16 249 return optional_attribute<T>::call(val);
Chris@16 250 }
Chris@16 251
Chris@16 252 inline unused_type optional_value(unused_type)
Chris@16 253 {
Chris@16 254 return unused;
Chris@16 255 }
Chris@16 256
Chris@16 257 template <typename T>
Chris@16 258 bool has_optional_value(T const& val)
Chris@16 259 {
Chris@16 260 return optional_attribute<T>::is_valid(val);
Chris@16 261 }
Chris@16 262
Chris@16 263 inline bool has_optional_value(unused_type)
Chris@16 264 {
Chris@16 265 return true;
Chris@16 266 }
Chris@16 267
Chris@16 268 ///////////////////////////////////////////////////////////////////////////
Chris@16 269 template <typename Container, typename T>
Chris@16 270 bool push_back(Container& c, T const& val);
Chris@16 271
Chris@16 272 //[customization_push_back_default
Chris@16 273 template <typename Container, typename T, typename Enable/* = void*/>
Chris@16 274 struct push_back_container
Chris@16 275 {
Chris@16 276 static bool call(Container& c, T const& val)
Chris@16 277 {
Chris@16 278 c.insert(c.end(), val);
Chris@16 279 return true;
Chris@16 280 }
Chris@16 281 };
Chris@16 282 //]
Chris@16 283
Chris@16 284 template <typename Container, typename T>
Chris@16 285 struct push_back_container<optional<Container>, T>
Chris@16 286 {
Chris@16 287 static bool call(boost::optional<Container>& c, T const& val)
Chris@16 288 {
Chris@16 289 if (!c)
Chris@16 290 c = Container();
Chris@16 291 return push_back(boost::get<Container>(c), val);
Chris@16 292 }
Chris@16 293 };
Chris@16 294
Chris@16 295 namespace detail
Chris@16 296 {
Chris@16 297 template <typename T>
Chris@16 298 struct push_back_visitor : public static_visitor<>
Chris@16 299 {
Chris@16 300 typedef bool result_type;
Chris@16 301
Chris@16 302 push_back_visitor(T const& t) : t_(t) {}
Chris@16 303
Chris@16 304 template <typename Container>
Chris@16 305 bool push_back_impl(Container& c, mpl::true_) const
Chris@16 306 {
Chris@16 307 return push_back(c, t_);
Chris@16 308 }
Chris@16 309
Chris@16 310 template <typename T_>
Chris@16 311 bool push_back_impl(T_&, mpl::false_) const
Chris@16 312 {
Chris@16 313 // this variant doesn't hold a container
Chris@16 314 BOOST_ASSERT(false && "This variant doesn't hold a container");
Chris@16 315 return false;
Chris@16 316 }
Chris@16 317
Chris@16 318 template <typename T_>
Chris@16 319 bool operator()(T_& c) const
Chris@16 320 {
Chris@16 321 return push_back_impl(c, typename is_container<T_>::type());
Chris@16 322 }
Chris@16 323
Chris@16 324 T const& t_;
Chris@16 325 };
Chris@16 326 }
Chris@16 327
Chris@16 328 template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T>
Chris@16 329 struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T>
Chris@16 330 {
Chris@16 331 static bool call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
Chris@16 332 {
Chris@16 333 return apply_visitor(detail::push_back_visitor<T>(val), c);
Chris@16 334 }
Chris@16 335 };
Chris@16 336
Chris@16 337 template <typename Container, typename T>
Chris@16 338 bool push_back(Container& c, T const& val)
Chris@16 339 {
Chris@16 340 return push_back_container<Container, T>::call(c, val);
Chris@16 341 }
Chris@16 342
Chris@16 343 //[customization_push_back_unused
Chris@16 344 template <typename Container>
Chris@16 345 bool push_back(Container&, unused_type)
Chris@16 346 {
Chris@16 347 return true;
Chris@16 348 }
Chris@16 349 //]
Chris@16 350
Chris@16 351 template <typename T>
Chris@16 352 bool push_back(unused_type, T const&)
Chris@16 353 {
Chris@16 354 return true;
Chris@16 355 }
Chris@16 356
Chris@16 357 inline bool push_back(unused_type, unused_type)
Chris@16 358 {
Chris@16 359 return true;
Chris@16 360 }
Chris@16 361
Chris@16 362 ///////////////////////////////////////////////////////////////////////////
Chris@16 363 template <typename Container, typename Enable/* = void*/>
Chris@16 364 struct is_empty_container
Chris@16 365 {
Chris@16 366 static bool call(Container const& c)
Chris@16 367 {
Chris@16 368 return c.empty();
Chris@16 369 }
Chris@16 370 };
Chris@16 371
Chris@16 372 template <typename Container>
Chris@16 373 bool is_empty(Container const& c)
Chris@16 374 {
Chris@16 375 return is_empty_container<Container>::call(c);
Chris@16 376 }
Chris@16 377
Chris@16 378 inline bool is_empty(unused_type)
Chris@16 379 {
Chris@16 380 return true;
Chris@16 381 }
Chris@16 382
Chris@16 383 ///////////////////////////////////////////////////////////////////////////
Chris@16 384 // Ensure the attribute is actually a container type
Chris@16 385 template <typename Container, typename Enable/* = void*/>
Chris@16 386 struct make_container_attribute
Chris@16 387 {
Chris@16 388 static void call(Container&)
Chris@16 389 {
Chris@16 390 // for static types this function does nothing
Chris@16 391 }
Chris@16 392 };
Chris@16 393
Chris@16 394 template <typename T>
Chris@16 395 void make_container(T& t)
Chris@16 396 {
Chris@16 397 make_container_attribute<T>::call(t);
Chris@16 398 }
Chris@16 399
Chris@16 400 inline void make_container(unused_type)
Chris@16 401 {
Chris@16 402 }
Chris@16 403
Chris@16 404 ///////////////////////////////////////////////////////////////////////////
Chris@16 405 template <typename Container, typename Enable/* = void*/>
Chris@16 406 struct begin_container
Chris@16 407 {
Chris@16 408 static typename container_iterator<Container>::type call(Container& c)
Chris@16 409 {
Chris@16 410 return c.begin();
Chris@16 411 }
Chris@16 412 };
Chris@16 413
Chris@16 414 template <typename Container>
Chris@16 415 typename spirit::result_of::begin<Container>::type
Chris@16 416 begin(Container& c)
Chris@16 417 {
Chris@16 418 return begin_container<Container>::call(c);
Chris@16 419 }
Chris@16 420
Chris@16 421 inline unused_type const*
Chris@16 422 begin(unused_type)
Chris@16 423 {
Chris@16 424 return &unused;
Chris@16 425 }
Chris@16 426
Chris@16 427 ///////////////////////////////////////////////////////////////////////////
Chris@16 428 template <typename Container, typename Enable/* = void*/>
Chris@16 429 struct end_container
Chris@16 430 {
Chris@16 431 static typename container_iterator<Container>::type call(Container& c)
Chris@16 432 {
Chris@16 433 return c.end();
Chris@16 434 }
Chris@16 435 };
Chris@16 436
Chris@16 437 template <typename Container>
Chris@16 438 inline typename spirit::result_of::end<Container>::type
Chris@16 439 end(Container& c)
Chris@16 440 {
Chris@16 441 return end_container<Container>::call(c);
Chris@16 442 }
Chris@16 443
Chris@16 444 inline unused_type const*
Chris@16 445 end(unused_type)
Chris@16 446 {
Chris@16 447 return &unused;
Chris@16 448 }
Chris@16 449
Chris@16 450 ///////////////////////////////////////////////////////////////////////////
Chris@16 451 template <typename Iterator, typename Enable/* = void*/>
Chris@16 452 struct deref_iterator
Chris@16 453 {
Chris@16 454 typedef typename boost::detail::iterator_traits<Iterator>::reference type;
Chris@16 455 static type call(Iterator& it)
Chris@16 456 {
Chris@16 457 return *it;
Chris@16 458 }
Chris@16 459 };
Chris@16 460
Chris@16 461 template <typename Iterator>
Chris@16 462 typename deref_iterator<Iterator>::type
Chris@16 463 deref(Iterator& it)
Chris@16 464 {
Chris@16 465 return deref_iterator<Iterator>::call(it);
Chris@16 466 }
Chris@16 467
Chris@16 468 inline unused_type
Chris@16 469 deref(unused_type const*)
Chris@16 470 {
Chris@16 471 return unused;
Chris@16 472 }
Chris@16 473
Chris@16 474 ///////////////////////////////////////////////////////////////////////////
Chris@16 475 template <typename Iterator, typename Enable/* = void*/>
Chris@16 476 struct next_iterator
Chris@16 477 {
Chris@16 478 static void call(Iterator& it)
Chris@16 479 {
Chris@16 480 ++it;
Chris@16 481 }
Chris@16 482 };
Chris@16 483
Chris@16 484 template <typename Iterator>
Chris@16 485 void next(Iterator& it)
Chris@16 486 {
Chris@16 487 next_iterator<Iterator>::call(it);
Chris@16 488 }
Chris@16 489
Chris@16 490 inline void next(unused_type const*)
Chris@16 491 {
Chris@16 492 // do nothing
Chris@16 493 }
Chris@16 494
Chris@16 495 ///////////////////////////////////////////////////////////////////////////
Chris@16 496 template <typename Iterator, typename Enable/* = void*/>
Chris@16 497 struct compare_iterators
Chris@16 498 {
Chris@16 499 static bool call(Iterator const& it1, Iterator const& it2)
Chris@16 500 {
Chris@16 501 return it1 == it2;
Chris@16 502 }
Chris@16 503 };
Chris@16 504
Chris@16 505 template <typename Iterator>
Chris@16 506 bool compare(Iterator& it1, Iterator& it2)
Chris@16 507 {
Chris@16 508 return compare_iterators<Iterator>::call(it1, it2);
Chris@16 509 }
Chris@16 510
Chris@16 511 inline bool compare(unused_type const*, unused_type const*)
Chris@16 512 {
Chris@16 513 return false;
Chris@16 514 }
Chris@16 515 }}}
Chris@16 516
Chris@16 517 ///////////////////////////////////////////////////////////////////////////////
Chris@16 518 namespace boost { namespace spirit { namespace result_of
Chris@16 519 {
Chris@16 520 ///////////////////////////////////////////////////////////////////////////
Chris@16 521 template <typename T>
Chris@16 522 struct optional_value
Chris@16 523 {
Chris@16 524 typedef T type;
Chris@16 525 };
Chris@16 526
Chris@16 527 template <typename T>
Chris@16 528 struct optional_value<boost::optional<T> >
Chris@16 529 {
Chris@16 530 typedef T type;
Chris@16 531 };
Chris@16 532
Chris@16 533 template <typename T>
Chris@16 534 struct optional_value<boost::optional<T> const>
Chris@16 535 {
Chris@16 536 typedef T const type;
Chris@16 537 };
Chris@16 538
Chris@16 539 template <>
Chris@16 540 struct optional_value<unused_type>
Chris@16 541 {
Chris@16 542 typedef unused_type type;
Chris@16 543 };
Chris@16 544
Chris@16 545 template <>
Chris@16 546 struct optional_value<unused_type const>
Chris@16 547 {
Chris@16 548 typedef unused_type type;
Chris@16 549 };
Chris@16 550
Chris@16 551 ///////////////////////////////////////////////////////////////////////////
Chris@16 552 template <typename Container>
Chris@16 553 struct begin
Chris@16 554 : traits::container_iterator<Container>
Chris@16 555 {};
Chris@16 556
Chris@16 557 template <typename Container>
Chris@16 558 struct end
Chris@16 559 : traits::container_iterator<Container>
Chris@16 560 {};
Chris@16 561
Chris@16 562 template <typename Iterator>
Chris@16 563 struct deref
Chris@16 564 : traits::deref_iterator<Iterator>
Chris@16 565 {};
Chris@16 566
Chris@16 567 template <>
Chris@16 568 struct deref<unused_type const*>
Chris@16 569 {
Chris@16 570 typedef unused_type type;
Chris@16 571 };
Chris@16 572
Chris@16 573 }}}
Chris@16 574
Chris@16 575 #endif