annotate DEPENDENCIES/generic/include/boost/spirit/home/support/container.hpp @ 133:4acb5d8d80b6 tip

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