ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/boost/foreach.hpp
Revision: 1.2
Committed: Sun Sep 9 20:05:51 2007 UTC (19 years, 1 month ago) by pippijn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +46 -1 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

File Contents

# Content
1 ///////////////////////////////////////////////////////////////////////////////
2 // foreach.hpp header file
3 //
4 // Copyright 2004 Eric Niebler.
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9
10 #ifndef BOOST_FOREACH
11
12 // MS compatible compilers support #pragma once
13 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
14 # pragma once
15 #endif
16
17 #include <cstddef>
18 #include <utility> // for std::pair
19
20 #include <boost/config.hpp>
21 #include <boost/detail/workaround.hpp>
22
23 #if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
24 || defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
25 || (defined(BOOST_INTEL_CXX_VERSION) && BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))\
26 || defined(__DECCXX_VER) && BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
27 # define BOOST_FOREACH_NO_LVALUE_RETURN_DETECTION
28 #endif
29
30 // Some compilers allow temporaries to be bound to non-const references.
31 // These compilers make it impossible to for BOOST_FOREACH to detect
32 // temporaries and avoid reevaluation of the collection expression.
33 #if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
34 || defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
35 || (defined(BOOST_INTEL_CXX_VERSION) && BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))
36 # define BOOST_FOREACH_NO_RVALUE_DETECTION
37 #endif
38
39 // Some compilers do not correctly implement the L-value/R-value conversion
40 // rules of the ternary conditional operator.
41 #if defined(BOOST_FOREACH_NO_RVALUE_DETECTION) \
42 || defined(BOOST_NO_SFINAE) \
43 || defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
44 || defined(BOOST_INTEL_WIN) && BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800)) \
45 || defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) \
46 || (defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ <= 2)) \
47 || defined(__IBMCPP__) && BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \
48 || defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570))
49 # define BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
50 #endif
51
52 #include <boost/mpl/bool.hpp>
53 #include <boost/mpl/eval_if.hpp>
54 #include <boost/range/end.hpp>
55 #include <boost/range/begin.hpp>
56 #include <boost/range/result_iterator.hpp>
57 #include <boost/type_traits/is_const.hpp>
58 #include <boost/iterator/iterator_traits.hpp>
59 #include <boost/utility/addressof.hpp>
60
61 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
62 # include <new>
63 # include <boost/aligned_storage.hpp>
64 # include <boost/utility/enable_if.hpp>
65 # include <boost/type_traits/is_array.hpp>
66 # include <boost/type_traits/remove_const.hpp>
67 #endif
68
69 namespace boost
70 {
71
72 // forward declarations for iterator_range
73 template<typename T>
74 class iterator_range;
75
76 // forward declarations for sub_range
77 template<typename T>
78 class sub_range;
79
80 namespace foreach
81 {
82
83 ///////////////////////////////////////////////////////////////////////////////
84 // in_range
85 //
86 template<typename T>
87 inline std::pair<T, T> in_range(T begin, T end)
88 {
89 return std::make_pair(begin, end);
90 }
91
92 } // namespace foreach
93
94 namespace foreach_detail_
95 {
96
97 ///////////////////////////////////////////////////////////////////////////////
98 // adl_begin/adl_end
99 //
100 template<typename T>
101 inline BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type adl_begin(T &t)
102 {
103 #if defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
104 || BOOST_WORKAROUND(__GNUC__, < 3)
105 return boost::begin(t);
106 #else
107 using boost::begin;
108 typedef BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type type;
109 return type(begin(t));
110 #endif
111 }
112
113 template<typename T>
114 inline BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type adl_end(T &t)
115 {
116 #if defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
117 || BOOST_WORKAROUND(__GNUC__, < 3)
118 return boost::end(t);
119 #else
120 using boost::end;
121 typedef BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type type;
122 return type(end(t));
123 #endif
124 }
125
126 ///////////////////////////////////////////////////////////////////////////////
127 // auto_any_t/auto_any
128 //
129 struct auto_any_base
130 {
131 // auto_any_base must evaluate to false in boolean context so that
132 // they can be declared in if() statements.
133 operator bool() const
134 {
135 return false;
136 }
137 };
138
139 template<typename T>
140 struct auto_any : auto_any_base
141 {
142 auto_any(T const &t)
143 : item(t)
144 {
145 }
146
147 // temporaries of type auto_any will be bound to const auto_any_base
148 // references, but we still want to be able to mutate the stored
149 // data, so declare it as mutable.
150 mutable T item;
151 };
152
153 typedef auto_any_base const &auto_any_t;
154
155 template<typename T, typename C>
156 inline BOOST_DEDUCED_TYPENAME boost::mpl::if_<C, T const, T>::type &auto_any_cast(auto_any_t a)
157 {
158 return static_cast<auto_any<T> const &>(a).item;
159 }
160
161 typedef boost::mpl::true_ const_;
162
163 ///////////////////////////////////////////////////////////////////////////////
164 // type2type
165 //
166 template<typename T, typename C = boost::mpl::false_>
167 struct type2type
168 : boost::mpl::if_<C, T const, T>
169 {
170 };
171
172 template<typename T, typename C = boost::mpl::false_>
173 struct foreach_iterator
174 {
175 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
176 C
177 , range_const_iterator<T>
178 , range_iterator<T>
179 >::type type;
180 };
181
182 template<typename T, typename C = boost::mpl::false_>
183 struct foreach_reference
184 : iterator_reference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
185 {
186 };
187
188 ///////////////////////////////////////////////////////////////////////////////
189 // encode_type
190 //
191 template<typename T>
192 inline type2type<T> *encode_type(T &, boost::mpl::false_ *)
193 {
194 return 0;
195 }
196
197 template<typename T>
198 inline type2type<T, const_> *encode_type(T const &, boost::mpl::true_ *)
199 {
200 return 0;
201 }
202
203 ///////////////////////////////////////////////////////////////////////////////
204 // encode_const
205 //
206 template<typename T>
207 inline boost::is_const<T> *encode_const(T &)
208 {
209 return 0;
210 }
211
212 #ifndef BOOST_FOREACH_NO_LVALUE_RETURN_DETECTION
213 template<typename T>
214 inline boost::mpl::true_ *encode_const(T const &)
215 {
216 return 0;
217 }
218 #endif
219
220 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
221
222 ///////////////////////////////////////////////////////////////////////////////
223 // rvalue_probe
224 //
225 struct rvalue_probe
226 {
227 template<typename T>
228 rvalue_probe(T const &t, bool &b)
229 : ptemp(const_cast<BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type *>(&t))
230 , rvalue(b)
231 {
232 }
233
234 template<typename U>
235 operator U()
236 {
237 rvalue = true;
238 return *static_cast<U *>(ptemp);
239 }
240
241 template<typename V>
242 operator V &() const
243 {
244 return *static_cast<V *>(ptemp);
245 }
246
247 void *ptemp;
248 bool &rvalue;
249 };
250
251 ///////////////////////////////////////////////////////////////////////////////
252 // simple_variant
253 // holds either a T or a T*
254 template<typename T>
255 struct simple_variant
256 {
257 simple_variant(T *t)
258 : rvalue(false)
259 {
260 *static_cast<T **>(data.address()) = t;
261 }
262
263 simple_variant(T const &t)
264 : rvalue(true)
265 {
266 ::new(data.address()) T(t);
267 }
268
269 simple_variant(simple_variant const &that)
270 : rvalue(that.rvalue)
271 {
272 if(rvalue)
273 ::new(data.address()) T(*that.get());
274 else
275 *static_cast<T **>(data.address()) = that.get();
276 }
277
278 ~simple_variant()
279 {
280 if(rvalue)
281 get()->~T();
282 }
283
284 T *get() const
285 {
286 if(rvalue)
287 return static_cast<T *>(data.address());
288 else
289 return *static_cast<T **>(data.address());
290 }
291
292 private:
293 enum { size = sizeof(T) > sizeof(T*) ? sizeof(T) : sizeof(T*) };
294 simple_variant &operator =(simple_variant const &);
295 bool const rvalue;
296 mutable aligned_storage<size> data;
297 };
298
299 #elif !defined(BOOST_FOREACH_NO_RVALUE_DETECTION)
300
301 ///////////////////////////////////////////////////////////////////////////////
302 // is_rvalue
303 //
304 template<typename T>
305 inline boost::mpl::false_ *is_rvalue(T &, int)
306 {
307 return 0;
308 }
309
310 template<typename T>
311 inline boost::mpl::true_ *is_rvalue(T const &, ...)
312 {
313 return 0;
314 }
315
316 #endif // BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
317
318 ///////////////////////////////////////////////////////////////////////////////
319 // set_false
320 //
321 inline bool set_false(bool &b)
322 {
323 return b = false;
324 }
325
326 ///////////////////////////////////////////////////////////////////////////////
327 // to_ptr
328 //
329 template<typename T>
330 inline T *to_ptr(T const &t) { return 0; }
331
332 // Borland needs a little extra help with arrays
333 #if defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
334 template<typename T,std::size_t N>
335 inline T (*to_ptr(T (&t)[N]))[N] { return 0; }
336 #endif
337
338 ///////////////////////////////////////////////////////////////////////////////
339 // cheap_copy
340 // Overload this for user-defined collection types if they are inexpensive to copy.
341 // This tells BOOST_FOREACH it can avoid the r-value/l-value detection stuff.
342 inline boost::mpl::false_ *cheap_copy(...) { return 0; }
343
344 template<typename T>
345 inline boost::mpl::true_ *cheap_copy(std::pair<T, T> *) { return 0; }
346
347 template<typename T>
348 inline boost::mpl::true_ *cheap_copy(iterator_range<T> *) { return 0; }
349
350 template<typename T>
351 inline boost::mpl::true_ *cheap_copy(sub_range<T> *) { return 0; }
352
353 template<typename T>
354 inline boost::mpl::true_ *cheap_copy(T **) { return 0; }
355
356 template<typename T,std::size_t N>
357 inline boost::mpl::false_ *cheap_copy(T (*)[N]) { return 0; }
358
359 ///////////////////////////////////////////////////////////////////////////////
360 // derefof
361 //
362 template<typename T>
363 inline T &derefof(T *t)
364 {
365 // This is a work-around for a compiler bug in Borland. If T* is a pointer to array type U(*)[N],
366 // then dereferencing it results in a U* instead of U(&)[N]. The cast forces the issue.
367 return reinterpret_cast<T &>(
368 *const_cast<char *>(
369 reinterpret_cast<char const volatile *>(t)
370 )
371 );
372 }
373
374 ///////////////////////////////////////////////////////////////////////////////
375 // contain
376 //
377 template<typename T>
378 inline auto_any<T> contain(T const &t, void *, boost::mpl::true_ *)
379 {
380 return t;
381 }
382
383 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
384 template<typename T>
385 inline auto_any<T *> contain(T &t, bool *, boost::mpl::false_ *)
386 {
387 return boost::addressof(t);
388 }
389
390 template<typename T>
391 inline BOOST_DEDUCED_TYPENAME disable_if<
392 boost::is_array<T>
393 , auto_any<simple_variant<T const> >
394 >::type
395 contain(T const &t, bool *rvalue, boost::mpl::false_ *)
396 {
397 return *rvalue ? simple_variant<T const>(t) : simple_variant<T const>(&t);
398 }
399 #else
400 template<typename T>
401 inline auto_any<T *> contain(T &t, boost::mpl::false_ *, boost::mpl::false_ *) // l-value
402 {
403 return boost::addressof(t);
404 }
405
406 template<typename T>
407 inline auto_any<T> contain(T const &t, boost::mpl::true_ *, boost::mpl::false_ *) // r-value
408 {
409 return t;
410 }
411 #endif
412
413 /////////////////////////////////////////////////////////////////////////////
414 // begin
415 //
416 template<typename T, typename C>
417 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
418 begin(auto_any_t col, type2type<T, C> *, void *, boost::mpl::true_ *)
419 {
420 return foreach_detail_::adl_begin(auto_any_cast<T, C>(col));
421 }
422
423 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
424 template<typename T, typename C>
425 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
426 begin(auto_any_t col, type2type<T, C> *, bool *, boost::mpl::false_ *)
427 {
428 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
429 return foreach_detail_::adl_begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)));
430 }
431
432 template<typename T>
433 inline BOOST_DEDUCED_TYPENAME disable_if<
434 boost::is_array<T>
435 , auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, boost::mpl::true_>::type>
436 >::type
437 begin(auto_any_t col, type2type<T, const_> *, bool *, boost::mpl::false_ *)
438 {
439 return foreach_detail_::adl_begin(*auto_any_cast<simple_variant<T const>, boost::mpl::false_>(col).get());
440 }
441 #else
442 template<typename T, typename C>
443 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
444 begin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *, boost::mpl::false_ *) // l-value
445 {
446 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
447 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator;
448 return iterator(foreach_detail_::adl_begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col))));
449 }
450
451 template<typename T>
452 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, boost::mpl::true_>::type>
453 begin(auto_any_t col, type2type<T, const_> *, boost::mpl::true_ *, boost::mpl::false_ *) // r-value
454 {
455 return foreach_detail_::adl_begin(auto_any_cast<T, boost::mpl::true_>(col));
456 }
457 #endif
458
459 ///////////////////////////////////////////////////////////////////////////////
460 // end
461 //
462 template<typename T, typename C>
463 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
464 end(auto_any_t col, type2type<T, C> *, void *, boost::mpl::true_ *)
465 {
466 return foreach_detail_::adl_end(auto_any_cast<T, C>(col));
467 }
468
469 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
470 template<typename T, typename C>
471 inline auto_any<int>
472 end(auto_any_t col, type2type<T *, C> *, void *, boost::mpl::true_ *)
473 {
474 return 0; // not used
475 }
476 #endif
477
478 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
479 template<typename T, typename C>
480 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
481 end(auto_any_t col, type2type<T, C> *, bool *, boost::mpl::false_ *)
482 {
483 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
484 return foreach_detail_::adl_end(derefof(auto_any_cast<type *, boost::mpl::false_>(col)));
485 }
486
487 template<typename T>
488 inline BOOST_DEDUCED_TYPENAME disable_if<
489 boost::is_array<T>
490 , auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, boost::mpl::true_>::type>
491 >::type
492 end(auto_any_t col, type2type<T, const_> *, bool *, boost::mpl::false_ *)
493 {
494 return foreach_detail_::adl_end(*auto_any_cast<simple_variant<T const>, boost::mpl::false_>(col).get());
495 }
496 #else
497 template<typename T, typename C>
498 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
499 end(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *, boost::mpl::false_ *) // l-value
500 {
501 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
502 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator;
503 return iterator(foreach_detail_::adl_end(derefof(auto_any_cast<type *, boost::mpl::false_>(col))));
504 }
505
506 template<typename T>
507 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, boost::mpl::true_>::type>
508 end(auto_any_t col, type2type<T, const_> *, boost::mpl::true_ *, boost::mpl::false_ *) // r-value
509 {
510 return foreach_detail_::adl_end(auto_any_cast<T, boost::mpl::true_>(col));
511 }
512 #endif
513
514 ///////////////////////////////////////////////////////////////////////////////
515 // done
516 //
517 template<typename T, typename C>
518 inline bool done(auto_any_t cur, auto_any_t end, type2type<T, C> *)
519 {
520 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
521 return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end);
522 }
523
524 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
525 template<typename T, typename C>
526 inline bool done(auto_any_t cur, auto_any_t, type2type<T *, C> *)
527 {
528 return ! *auto_any_cast<T *, boost::mpl::false_>(cur);
529 }
530 #endif
531
532 ///////////////////////////////////////////////////////////////////////////////
533 // next
534 //
535 template<typename T, typename C>
536 inline void next(auto_any_t cur, type2type<T, C> *)
537 {
538 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
539 ++auto_any_cast<iter_t, boost::mpl::false_>(cur);
540 }
541
542 ///////////////////////////////////////////////////////////////////////////////
543 // deref
544 //
545 template<typename T, typename C>
546 inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type
547 deref(auto_any_t cur, type2type<T, C> *)
548 {
549 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
550 return *auto_any_cast<iter_t, boost::mpl::false_>(cur);
551 }
552
553 } // namespace foreach_detail_
554 } // namespace boost
555
556 #ifndef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
557 ///////////////////////////////////////////////////////////////////////////////
558 // R-values and const R-values supported here
559 ///////////////////////////////////////////////////////////////////////////////
560
561 // A sneaky way to get the type of the collection without evaluating the expression
562 # define BOOST_FOREACH_TYPEOF(COL) \
563 (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::encode_const(COL)))
564
565 // Evaluate the collection expression, and detect if it is an l-value or and r-value
566 # define BOOST_FOREACH_EVAL(COL) \
567 (true ? boost::foreach_detail_::rvalue_probe((COL), _foreach_rvalue) : (COL))
568
569 // Declare a variable to track the rvalue-ness of the collection expression
570 # define BOOST_FOREACH_DEFINE_RVALUE() \
571 if (bool _foreach_rvalue = false) {} else
572
573 // The R-value/L-value-ness of the collection expression is determined dynamically
574 # define BOOST_FOREACH_RVALUE(COL) \
575 (&_foreach_rvalue)
576
577 # define BOOST_FOREACH_CHEAP_COPY(COL) \
578 (true ? 0 : boost::foreach_detail_::cheap_copy(boost::foreach_detail_::to_ptr(COL)))
579
580 # define BOOST_FOREACH_NOOP(COL) \
581 ((void)0)
582
583 #elif !defined(BOOST_FOREACH_NO_RVALUE_DETECTION)
584 ///////////////////////////////////////////////////////////////////////////////
585 // R-values supported here, const R-values NOT supported here
586 ///////////////////////////////////////////////////////////////////////////////
587
588 // A sneaky way to get the type of the collection without evaluating the expression
589 # define BOOST_FOREACH_TYPEOF(COL) \
590 (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::encode_const(COL)))
591
592 // Evaluate the collection expression
593 # define BOOST_FOREACH_EVAL(COL) \
594 (COL)
595
596 // No variable is needed to track the rvalue-ness of the collection expression
597 # define BOOST_FOREACH_DEFINE_RVALUE() \
598 /**/
599
600 // Determine whether the collection expression is an l-value or an r-value.
601 // NOTE: this gets the answer for const R-values wrong.
602 # define BOOST_FOREACH_RVALUE(COL) \
603 (true ? 0 : boost::foreach_detail_::is_rvalue((COL), 0))
604
605 # define BOOST_FOREACH_CHEAP_COPY(COL) \
606 (true ? 0 : boost::foreach_detail_::cheap_copy(boost::foreach_detail_::to_ptr(COL)))
607
608 # define BOOST_FOREACH_NOOP(COL) \
609 ((void)0)
610
611 #else
612 ///////////////////////////////////////////////////////////////////////////////
613 // R-values NOT supported here
614 ///////////////////////////////////////////////////////////////////////////////
615
616 // A sneaky way to get the type of the collection without evaluating the expression
617 # define BOOST_FOREACH_TYPEOF(COL) \
618 (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::encode_const(COL)))
619
620 // Evaluate the collection expression
621 # define BOOST_FOREACH_EVAL(COL) \
622 (COL)
623
624 // No variable is needed to track the rvalue-ness of the collection expression
625 # define BOOST_FOREACH_DEFINE_RVALUE() \
626 /**/
627
628 // Can't use R-values with BOOST_FOREACH
629 # define BOOST_FOREACH_RVALUE(COL) \
630 (static_cast<boost::mpl::false_ *>(0))
631
632 # define BOOST_FOREACH_CHEAP_COPY(COL) \
633 (true ? 0 : boost::foreach_detail_::cheap_copy(boost::foreach_detail_::to_ptr(COL)))
634
635 // Attempt to make uses of BOOST_FOREACH with non-lvalues fail to compile
636 // BUGBUG but cheap-to-copy containers *would* be handled correctly. Hrm.
637 # define BOOST_FOREACH_NOOP(COL) \
638 ((void)&(COL))
639
640 #endif
641
642
643 #define BOOST_FOREACH_CONTAIN(COL) \
644 boost::foreach_detail_::contain( \
645 BOOST_FOREACH_EVAL(COL) \
646 , BOOST_FOREACH_RVALUE(COL) \
647 , BOOST_FOREACH_CHEAP_COPY(COL))
648
649 #define BOOST_FOREACH_BEGIN(COL) \
650 boost::foreach_detail_::begin( \
651 _foreach_col \
652 , BOOST_FOREACH_TYPEOF(COL) \
653 , BOOST_FOREACH_RVALUE(COL) \
654 , BOOST_FOREACH_CHEAP_COPY(COL))
655
656 #define BOOST_FOREACH_END(COL) \
657 boost::foreach_detail_::end( \
658 _foreach_col \
659 , BOOST_FOREACH_TYPEOF(COL) \
660 , BOOST_FOREACH_RVALUE(COL) \
661 , BOOST_FOREACH_CHEAP_COPY(COL))
662
663 #define BOOST_FOREACH_DONE(COL) \
664 boost::foreach_detail_::done( \
665 _foreach_cur \
666 , _foreach_end \
667 , BOOST_FOREACH_TYPEOF(COL))
668
669 #define BOOST_FOREACH_NEXT(COL) \
670 boost::foreach_detail_::next( \
671 _foreach_cur \
672 , BOOST_FOREACH_TYPEOF(COL))
673
674 #define BOOST_FOREACH_DEREF(COL) \
675 boost::foreach_detail_::deref( \
676 _foreach_cur \
677 , BOOST_FOREACH_TYPEOF(COL))
678
679 ///////////////////////////////////////////////////////////////////////////////
680 // BOOST_FOREACH
681 //
682 // For iterating over collections. Collections can be
683 // arrays, null-terminated strings, or STL containers.
684 // The loop variable can be a value or reference. For
685 // example:
686 //
687 // std::list<int> int_list(/*stuff*/);
688 // BOOST_FOREACH(int &i, int_list)
689 // {
690 // /*
691 // * loop body goes here.
692 // * i is a reference to the int in int_list.
693 // */
694 // }
695 //
696 // Alternately, you can declare the loop variable first,
697 // so you can access it after the loop finishes. Obviously,
698 // if you do it this way, then the loop variable cannot be
699 // a reference.
700 //
701 // int i;
702 // BOOST_FOREACH(i, int_list)
703 // { ... }
704 //
705 #define BOOST_FOREACH(VAR, COL) \
706 BOOST_FOREACH_DEFINE_RVALUE() \
707 if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else \
708 if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_BEGIN(COL)) {} else \
709 if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_END(COL)) {} else \
710 for (bool _foreach_continue = true; \
711 _foreach_continue && !BOOST_FOREACH_DONE(COL); \
712 _foreach_continue ? BOOST_FOREACH_NEXT(COL) : BOOST_FOREACH_NOOP(COL)) \
713 if (boost::foreach_detail_::set_false(_foreach_continue)) {} else \
714 for (VAR = BOOST_FOREACH_DEREF(COL); !_foreach_continue; _foreach_continue = true)
715
716 #define foreach BOOST_FOREACH
717
718 #endif