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

# User Rev Content
1 pippijn 1.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 pippijn 1.2 #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 pippijn 1.1 #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 pippijn 1.2 #if defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
104     || BOOST_WORKAROUND(__GNUC__, < 3)
105     return boost::begin(t);
106     #else
107 pippijn 1.1 using boost::begin;
108     typedef BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type type;
109     return type(begin(t));
110 pippijn 1.2 #endif
111 pippijn 1.1 }
112    
113     template<typename T>
114     inline BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type adl_end(T &t)
115     {
116 pippijn 1.2 #if defined(__BORLANDC__) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
117     || BOOST_WORKAROUND(__GNUC__, < 3)
118     return boost::end(t);
119     #else
120 pippijn 1.1 using boost::end;
121     typedef BOOST_DEDUCED_TYPENAME range_result_iterator<T>::type type;
122     return type(end(t));
123 pippijn 1.2 #endif
124 pippijn 1.1 }
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 pippijn 1.2 // 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 pippijn 1.1 ///////////////////////////////////////////////////////////////////////////////
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 pippijn 1.2 #define foreach BOOST_FOREACH
717 pippijn 1.1
718     #endif