Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-06-19 22:14:05


Author: eric_niebler
Date: 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
New Revision: 46538
URL: http://svn.boost.org/trac/boost/changeset/46538

Log:
latest BOOST_FOREACH
Added:
   branches/release/libs/foreach/test/array_byref_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/array_byval_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/cstr_byref_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/cstr_byval_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/misc.cpp (contents, props changed)
   branches/release/libs/foreach/test/pair_byref_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/pair_byval_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/rvalue_const_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/rvalue_nonconst_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/stl_byref_r.cpp (contents, props changed)
   branches/release/libs/foreach/test/stl_byval_r.cpp (contents, props changed)
Text files modified:
   branches/release/boost/foreach.hpp | 230 ++++++++++++++++++++++++++++++++++++---
   branches/release/libs/foreach/doc/foreach.qbk | 11 +
   branches/release/libs/foreach/test/Jamfile.v2 | 11 +
   branches/release/libs/foreach/test/rvalue_const.cpp | 3
   branches/release/libs/foreach/test/utility.hpp | 64 +++++++++++
   5 files changed, 300 insertions(+), 19 deletions(-)

Modified: branches/release/boost/foreach.hpp
==============================================================================
--- branches/release/boost/foreach.hpp (original)
+++ branches/release/boost/foreach.hpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -42,7 +42,7 @@
   || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
   || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
   || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) \
- || BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+ || BOOST_WORKAROUND(__DECCXX_VER, <= 60590042)
 # define BOOST_FOREACH_NO_RVALUE_DETECTION
 # endif
 // Some compilers do not correctly implement the lvalue/rvalue conversion
@@ -69,7 +69,10 @@
 #include <boost/noncopyable.hpp>
 #include <boost/range/end.hpp>
 #include <boost/range/begin.hpp>
+#include <boost/range/rend.hpp>
+#include <boost/range/rbegin.hpp>
 #include <boost/range/iterator.hpp>
+#include <boost/range/reverse_iterator.hpp>
 #include <boost/type_traits/is_array.hpp>
 #include <boost/type_traits/is_const.hpp>
 #include <boost/type_traits/is_abstract.hpp>
@@ -202,15 +205,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Define some utilities for assessing the properties of expressions
 //
-typedef char yes_type;
-typedef char (&no_type)[2];
-yes_type is_true(boost::mpl::true_ *);
-no_type is_true(boost::mpl::false_ *);
-
-// Extracts the desired property from the expression without evaluating it
-#define BOOST_FOREACH_PROTECT(expr) \
- (static_cast<boost::mpl::bool_<1 == sizeof(boost::foreach_detail_::is_true(expr))> *>(0))
-
 template<typename Bool1, typename Bool2>
 inline boost::mpl::and_<Bool1, Bool2> *and_(Bool1 *, Bool2 *) { return 0; }
 
@@ -368,6 +362,37 @@
>::type type;
 };
 
+
+template<typename T, typename C = boost::mpl::false_>
+struct foreach_reverse_iterator
+{
+ // **** READ THIS IF YOUR COMPILE BREAKS HERE ****
+ //
+ // There is an ambiguity about how to iterate over arrays of char and wchar_t.
+ // Should the last array element be treated as a null terminator to be skipped, or
+ // is it just like any other element in the array? To fix the problem, you must
+ // say which behavior you want.
+ //
+ // To treat the container as a null-terminated string, merely cast it to a
+ // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ...
+ //
+ // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>,
+ // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ...
+ #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+ BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) );
+ #endif
+
+ // If the type is a pointer to a null terminated string (as opposed
+ // to an array type), there is no ambiguity.
+ typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container;
+
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
+ C
+ , range_reverse_iterator<container const>
+ , range_reverse_iterator<container>
+ >::type type;
+};
+
 template<typename T, typename C = boost::mpl::false_>
 struct foreach_reference
   : iterator_reference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>
@@ -386,7 +411,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // set_false
 //
-inline bool set_false(bool &b) { return b = false; }
+inline bool set_false(bool &b)
+{
+ b = false;
+ return false;
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 // to_ptr
@@ -441,17 +470,20 @@
     typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
         boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T
>::type value_type;
- operator value_type();
- operator T &() const;
+ operator value_type() { return *reinterpret_cast<value_type *>(this); } // never called
+ operator T &() const { return *reinterpret_cast<T *>(const_cast<rvalue_probe *>(this)); } // never called
 };
 
 template<typename T>
-rvalue_probe<T> const make_probe(T const &t);
+rvalue_probe<T> const make_probe(T const &)
+{
+ return rvalue_probe<T>();
+}
 
 # define BOOST_FOREACH_IS_RVALUE(COL) \
     boost::foreach_detail_::and_( \
         boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(COL)) \
- , BOOST_FOREACH_PROTECT(boost::foreach_detail_::is_rvalue_( \
+ , (true ? 0 : boost::foreach_detail_::is_rvalue_( \
             (true ? boost::foreach_detail_::make_probe(COL) : (COL)), 0)))
 
 #elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION)
@@ -717,9 +749,124 @@
     return *auto_any_cast<iter_t, boost::mpl::false_>(cur);
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// rbegin
+//
+template<typename T, typename C>
+inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>
+rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue
+{
+ return boost::rbegin(auto_any_cast<T, C>(col));
+}
+
+template<typename T, typename C>
+inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>
+rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue
+{
+ typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
+ typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator;
+ return iterator(boost::rbegin(derefof(auto_any_cast<type *, boost::mpl::false_>(col))));
+}
+
+#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION
+template<typename T>
+auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>
+rbegin(auto_any_t col, type2type<T, const_> *, bool *)
+{
+ return boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get());
+}
+#endif
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+template<typename T, typename C>
+inline auto_any<reverse_iterator<T *> >
+rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings
+{
+ T *p = auto_any_cast<T *, boost::mpl::false_>(col);
+ while(0 != *p)
+ ++p;
+ return reverse_iterator<T *>(p);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// rend
+//
+template<typename T, typename C>
+inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>
+rend(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue
+{
+ return boost::rend(auto_any_cast<T, C>(col));
+}
+
+template<typename T, typename C>
+inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>
+rend(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue
+{
+ typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type;
+ typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator;
+ return iterator(boost::rend(derefof(auto_any_cast<type *, boost::mpl::false_>(col))));
+}
+
+#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION
+template<typename T>
+auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>
+rend(auto_any_t col, type2type<T, const_> *, bool *)
+{
+ return boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get());
+}
+#endif
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+template<typename T, typename C>
+inline auto_any<reverse_iterator<T *> >
+rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings
+{
+ return reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col));
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// rdone
+//
+template<typename T, typename C>
+inline bool rdone(auto_any_t cur, auto_any_t end, type2type<T, C> *)
+{
+ typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t;
+ return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// rnext
+//
+template<typename T, typename C>
+inline void rnext(auto_any_t cur, type2type<T, C> *)
+{
+ typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t;
+ ++auto_any_cast<iter_t, boost::mpl::false_>(cur);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// rderef
+//
+template<typename T, typename C>
+inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type
+rderef(auto_any_t cur, type2type<T, C> *)
+{
+ typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t;
+ return *auto_any_cast<iter_t, boost::mpl::false_>(cur);
+}
+
 } // namespace foreach_detail_
 } // namespace boost
 
+// Suppress a bogus code analysis warning on vc8+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# define BOOST_FOREACH_SUPPRESS_WARNINGS() __pragma(warning(suppress:6001))
+#else
+# define BOOST_FOREACH_SUPPRESS_WARNINGS()
+#endif
+
 // A sneaky way to get the type of the collection without evaluating the expression
 #define BOOST_FOREACH_TYPEOF(COL) \
     (true ? 0 : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::is_const_(COL)))
@@ -745,7 +892,7 @@
 
 // No variable is needed to track the rvalue-ness of the collection expression
 # define BOOST_FOREACH_PREAMBLE() \
- /**/
+ BOOST_FOREACH_SUPPRESS_WARNINGS()
 
 // Evaluate the collection expression
 # define BOOST_FOREACH_EVALUATE(COL) \
@@ -763,6 +910,7 @@
 
 // Declare a variable to track the rvalue-ness of the collection expression
 # define BOOST_FOREACH_PREAMBLE() \
+ BOOST_FOREACH_SUPPRESS_WARNINGS() \
     if (bool _foreach_is_rvalue = false) {} else
 
 // Evaluate the collection expression, and detect if it is an lvalue or and rvalue
@@ -788,7 +936,7 @@
 
 // No variable is needed to track the rvalue-ness of the collection expression
 # define BOOST_FOREACH_PREAMBLE() \
- /**/
+ BOOST_FOREACH_SUPPRESS_WARNINGS()
 
 // Evaluate the collection expression
 # define BOOST_FOREACH_EVALUATE(COL) \
@@ -808,7 +956,7 @@
 
 // No variable is needed to track the rvalue-ness of the collection expression
 # define BOOST_FOREACH_PREAMBLE() \
- /**/
+ BOOST_FOREACH_SUPPRESS_WARNINGS()
 
 // Evaluate the collection expression
 # define BOOST_FOREACH_EVALUATE(COL) \
@@ -853,6 +1001,34 @@
         _foreach_cur \
       , BOOST_FOREACH_TYPEOF(COL))
 
+#define BOOST_FOREACH_RBEGIN(COL) \
+ boost::foreach_detail_::rbegin( \
+ _foreach_col \
+ , BOOST_FOREACH_TYPEOF(COL) \
+ , BOOST_FOREACH_SHOULD_COPY(COL))
+
+#define BOOST_FOREACH_REND(COL) \
+ boost::foreach_detail_::rend( \
+ _foreach_col \
+ , BOOST_FOREACH_TYPEOF(COL) \
+ , BOOST_FOREACH_SHOULD_COPY(COL))
+
+#define BOOST_FOREACH_RDONE(COL) \
+ boost::foreach_detail_::rdone( \
+ _foreach_cur \
+ , _foreach_end \
+ , BOOST_FOREACH_TYPEOF(COL))
+
+#define BOOST_FOREACH_RNEXT(COL) \
+ boost::foreach_detail_::rnext( \
+ _foreach_cur \
+ , BOOST_FOREACH_TYPEOF(COL))
+
+#define BOOST_FOREACH_RDEREF(COL) \
+ boost::foreach_detail_::rderef( \
+ _foreach_cur \
+ , BOOST_FOREACH_TYPEOF(COL))
+
 ///////////////////////////////////////////////////////////////////////////////
 // BOOST_FOREACH
 //
@@ -890,4 +1066,22 @@
         if (boost::foreach_detail_::set_false(_foreach_continue)) {} else \
         for (VAR = BOOST_FOREACH_DEREF(COL); !_foreach_continue; _foreach_continue = true)
 
+///////////////////////////////////////////////////////////////////////////////
+// BOOST_REVERSE_FOREACH
+//
+// For iterating over collections in reverse order. In
+// all other respects, BOOST_REVERSE_FOREACH is like
+// BOOST_FOREACH.
+//
+#define BOOST_REVERSE_FOREACH(VAR, COL) \
+ BOOST_FOREACH_PREAMBLE() \
+ if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_RBEGIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_REND(COL)) {} else \
+ for (bool _foreach_continue = true; \
+ _foreach_continue && !BOOST_FOREACH_RDONE(COL); \
+ _foreach_continue ? BOOST_FOREACH_RNEXT(COL) : (void)0) \
+ if (boost::foreach_detail_::set_false(_foreach_continue)) {} else \
+ for (VAR = BOOST_FOREACH_RDEREF(COL); !_foreach_continue; _foreach_continue = true)
+
 #endif

Modified: branches/release/libs/foreach/doc/foreach.qbk
==============================================================================
--- branches/release/libs/foreach/doc/foreach.qbk (original)
+++ branches/release/libs/foreach/doc/foreach.qbk 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -162,6 +162,14 @@
         // Note: get_vector_float() will be called exactly once
     }
 
+Iterate in reverse:
+
+ std::list<int> list_int( /*...*/ );
+ BOOST_REVERSE_FOREACH( int i, list_int )
+ {
+ // do something with i
+ }
+
 Iterating over rvalues doesn't work on some older compilers. Check the
 [link foreach.portability Portability] section to see whether your
 compiler supports this.
@@ -174,7 +182,8 @@
 doesn't mean you're stuck with it, though. If you would like to use a different
 identifier (`foreach`, perhaps), you can simply do:
 
- #define foreach BOOST_FOREACH
+ #define foreach BOOST_FOREACH
+ #define reverse_foreach BOOST_REVERSE_FOREACH
 
 Only do this if you are sure that the identifier you choose will not cause
 name conflicts in your code.

Modified: branches/release/libs/foreach/test/Jamfile.v2
==============================================================================
--- branches/release/libs/foreach/test/Jamfile.v2 (original)
+++ branches/release/libs/foreach/test/Jamfile.v2 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -8,16 +8,27 @@
 test-suite "foreach"
     : [ run stl_byval.cpp ]
       [ run stl_byref.cpp ]
+ [ run stl_byval_r.cpp ]
+ [ run stl_byref_r.cpp ]
       [ run array_byval.cpp ]
       [ run array_byref.cpp ]
+ [ run array_byval_r.cpp ]
+ [ run array_byref_r.cpp ]
       [ run cstr_byval.cpp ]
       [ run cstr_byref.cpp ]
+ [ run cstr_byval_r.cpp ]
+ [ run cstr_byref_r.cpp ]
       [ run pair_byval.cpp ]
       [ run pair_byref.cpp ]
+ [ run pair_byval_r.cpp ]
+ [ run pair_byref_r.cpp ]
       [ run user_defined.cpp ]
       [ run call_once.cpp ]
       [ run rvalue_const.cpp ]
       [ run rvalue_nonconst.cpp ]
+ [ run rvalue_const_r.cpp ]
+ [ run rvalue_nonconst_r.cpp ]
       [ run dependent_type.cpp ]
+ [ run misc.cpp ]
       [ compile noncopyable.cpp ]
     ;

Added: branches/release/libs/foreach/test/array_byref_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/array_byref_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,48 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef int foreach_container_type[5];
+typedef int const foreach_const_container_type[5];
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+int my_array[5] = { 1,2,3,4,5 };
+int const (&my_const_array)[5] = my_array;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ // non-const containers by reference
+ BOOST_CHECK(sequence_equal_byref_n_r(my_array, "\5\4\3\2\1"));
+
+ // const containers by reference
+ BOOST_CHECK(sequence_equal_byref_c_r(my_const_array, "\5\4\3\2\1"));
+
+ // mutate the mutable collections
+ mutate_foreach_byref_r(my_array);
+
+ // compare the mutated collections to the actual results
+ BOOST_CHECK(sequence_equal_byref_n_r(my_array, "\6\5\4\3\2"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/array_byval_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/array_byval_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,44 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef int foreach_container_type[5];
+typedef int const foreach_const_container_type[5];
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+int my_array[5] = { 1,2,3,4,5 };
+int const (&my_const_array)[5] = my_array;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ boost::mpl::false_ *p = BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(my_array);
+
+ // non-const containers by value
+ BOOST_CHECK(sequence_equal_byval_n_r(my_array, "\5\4\3\2\1"));
+
+ // const containers by value
+ BOOST_CHECK(sequence_equal_byval_c_r(my_const_array, "\5\4\3\2\1"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/cstr_byref_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/cstr_byref_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,49 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef char *foreach_container_type;
+typedef char const *foreach_const_container_type;
+typedef char foreach_value_type;
+typedef char &foreach_reference_type;
+typedef char const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+char my_ntcs_buffer[] = "\1\2\3\4\5";
+char *my_ntcs = my_ntcs_buffer;
+char const *my_const_ntcs = my_ntcs;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ // non-const containers by reference
+ BOOST_CHECK(sequence_equal_byref_n_r(my_ntcs, "\5\4\3\2\1"));
+
+ // const containers by reference
+ BOOST_CHECK(sequence_equal_byref_c_r(my_const_ntcs, "\5\4\3\2\1"));
+
+ // mutate the mutable collections
+ mutate_foreach_byref_r(my_ntcs);
+
+ // compare the mutated collections to the actual results
+ BOOST_CHECK(sequence_equal_byref_n_r(my_ntcs, "\6\5\4\3\2"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/cstr_byval_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/cstr_byval_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,45 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef char *foreach_container_type;
+typedef char const *foreach_const_container_type;
+typedef char foreach_value_type;
+typedef char &foreach_reference_type;
+typedef char const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+char my_ntcs_buffer[] = "\1\2\3\4\5";
+char *my_ntcs = my_ntcs_buffer;
+char const *my_const_ntcs = my_ntcs;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ boost::mpl::true_ *p = BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(my_ntcs);
+
+ // non-const containers by value
+ BOOST_CHECK(sequence_equal_byval_n_r(my_ntcs, "\5\4\3\2\1"));
+
+ // const containers by value
+ BOOST_CHECK(sequence_equal_byval_c_r(my_const_ntcs, "\5\4\3\2\1"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/misc.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/misc.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,47 @@
+// misc.cpp
+//
+// (C) Copyright Eric Niebler 2008.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 4 March 2008 : Initial version.
+*/
+
+#include <vector>
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+struct xxx : std::vector<int>
+{
+ virtual ~xxx() = 0;
+};
+
+void test_abstract(xxx& rng)
+{
+ BOOST_FOREACH (int x, rng)
+ {
+ (void)x;
+ }
+}
+
+struct yyy : std::vector<int>
+{
+ void test()
+ {
+ BOOST_FOREACH(int x, *this)
+ {
+ (void)x;
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ return 0;
+}

Added: branches/release/libs/foreach/test/pair_byref_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/pair_byref_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,50 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 13 December 2004 : Initial version.
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef std::pair<int*,int*> foreach_container_type;
+typedef std::pair<int const*,int const*> const foreach_const_container_type;
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+int my_array[] = { 1,2,3,4,5 };
+std::pair<int*,int*> my_pair(my_array,my_array+5);
+std::pair<int const*,int const*> const my_const_pair(my_array,my_array+5);
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ // non-const containers by reference
+ BOOST_CHECK(sequence_equal_byref_n_r(my_pair, "\5\4\3\2\1"));
+
+ // const containers by reference
+ BOOST_CHECK(sequence_equal_byref_c_r(my_const_pair, "\5\4\3\2\1"));
+
+ // mutate the mutable collections
+ mutate_foreach_byref_r(my_pair);
+
+ // compare the mutated collections to the actual results
+ BOOST_CHECK(sequence_equal_byref_n_r(my_pair, "\6\5\4\3\2"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/pair_byval_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/pair_byval_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,45 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef std::pair<int*,int*> foreach_container_type;
+typedef std::pair<int const*,int const*> const foreach_const_container_type;
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+int my_array[] = { 1,2,3,4,5 };
+std::pair<int*,int*> my_pair(my_array,my_array+5);
+std::pair<int const*,int const*> const my_const_pair(my_array,my_array+5);
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ boost::mpl::true_ *p = BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(my_pair);
+
+ // non-const containers by value
+ BOOST_CHECK(sequence_equal_byval_n_r(my_pair, "\5\4\3\2\1"));
+
+ // const containers by value
+ BOOST_CHECK(sequence_equal_byval_c_r(my_const_pair, "\5\4\3\2\1"));
+
+ return 0;
+}

Modified: branches/release/libs/foreach/test/rvalue_const.cpp
==============================================================================
--- branches/release/libs/foreach/test/rvalue_const.cpp (original)
+++ branches/release/libs/foreach/test/rvalue_const.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -13,7 +13,10 @@
 #include <boost/foreach.hpp>
 
 #ifdef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
+// ignore error during Microsoft Code Analysis
+#if !defined(_PREFAST_)
 # error Expected failure : const rvalues disallowed
+#endif
 #else
 
 std::vector<int> const get_vector()

Added: branches/release/libs/foreach/test/rvalue_const_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/rvalue_const_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,44 @@
+// (C) Copyright Eric Niebler 2005.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <vector>
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+#ifdef BOOST_FOREACH_NO_CONST_RVALUE_DETECTION
+// ignore error during Microsoft Code Analysis
+#if !defined(_PREFAST_)
+# error Expected failure : const rvalues disallowed
+#endif
+#else
+
+std::vector<int> const get_vector()
+{
+ return std::vector<int>(4, 4);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ int counter = 0;
+
+ BOOST_REVERSE_FOREACH(int i, get_vector())
+ {
+ counter += i;
+ }
+
+ BOOST_CHECK(16 == counter);
+
+ return 0;
+}
+
+#endif

Added: branches/release/libs/foreach/test/rvalue_nonconst_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/rvalue_nonconst_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,41 @@
+// (C) Copyright Eric Niebler 2005.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <vector>
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+#ifdef BOOST_FOREACH_NO_RVALUE_DETECTION
+# error Expected failure : rvalues disallowed
+#else
+
+std::vector<int> get_vector()
+{
+ return std::vector<int>(4, 4);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ int counter = 0;
+
+ BOOST_REVERSE_FOREACH(int i, get_vector())
+ {
+ counter += i;
+ }
+
+ BOOST_CHECK(16 == counter);
+
+ return 0;
+}
+
+#endif

Added: branches/release/libs/foreach/test/stl_byref_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/stl_byref_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,62 @@
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005: Initial version.
+*/
+
+#include <list>
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef std::list<int> foreach_container_type;
+typedef std::list<int> const foreach_const_container_type;
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// initialize a std::list<int>
+std::list<int> make_list()
+{
+ std::list<int> l;
+ l.push_back(1);
+ l.push_back(2);
+ l.push_back(3);
+ l.push_back(4);
+ l.push_back(5);
+ return l;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+std::list<int> my_list = make_list();
+std::list<int> const &my_const_list = my_list;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ // non-const containers by reference
+ BOOST_CHECK(sequence_equal_byref_n_r(my_list, "\5\4\3\2\1"));
+
+ // const containers by reference
+ BOOST_CHECK(sequence_equal_byref_c_r(my_const_list, "\5\4\3\2\1"));
+
+ // mutate the mutable collections
+ mutate_foreach_byref_r(my_list);
+
+ // compare the mutated collections to the actual results
+ BOOST_CHECK(sequence_equal_byref_n_r(my_list, "\6\5\4\3\2"));
+
+ return 0;
+}

Added: branches/release/libs/foreach/test/stl_byval_r.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/foreach/test/stl_byval_r.cpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,60 @@
+// stl_byval.cpp
+///
+// (C) Copyright Eric Niebler 2004.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ Revision history:
+ 25 August 2005 : Initial version.
+*/
+
+#include <list>
+#include <boost/test/minimal.hpp>
+#include <boost/foreach.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// define the container types, used by utility.hpp to generate the helper functions
+typedef std::list<int> foreach_container_type;
+typedef std::list<int> const foreach_const_container_type;
+typedef int foreach_value_type;
+typedef int &foreach_reference_type;
+typedef int const &foreach_const_reference_type;
+
+#include "./utility.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// initialize a std::list<int>
+std::list<int> make_list()
+{
+ std::list<int> l;
+ l.push_back(1);
+ l.push_back(2);
+ l.push_back(3);
+ l.push_back(4);
+ l.push_back(5);
+ return l;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// define some containers
+//
+std::list<int> my_list = make_list();
+std::list<int> const &my_const_list = my_list;
+
+///////////////////////////////////////////////////////////////////////////////
+// test_main
+//
+int test_main( int, char*[] )
+{
+ boost::mpl::false_ *p = BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(my_list);
+
+ // non-const containers by value
+ BOOST_CHECK(sequence_equal_byval_n_r(my_list, "\5\4\3\2\1"));
+
+ // const containers by value
+ BOOST_CHECK(sequence_equal_byval_c_r(my_const_list, "\5\4\3\2\1"));
+
+ return 0;
+}

Modified: branches/release/libs/foreach/test/utility.hpp
==============================================================================
--- branches/release/libs/foreach/test/utility.hpp (original)
+++ branches/release/libs/foreach/test/utility.hpp 2008-06-19 22:14:03 EDT (Thu, 19 Jun 2008)
@@ -76,4 +76,68 @@
     }
 }
 
+
+///////////////////////////////////////////////////////////////////////////////
+// sequence_equal_byval_n_r
+inline bool sequence_equal_byval_n_r( foreach_container_type & rng, char const * result )
+{
+ BOOST_REVERSE_FOREACH( foreach_value_type i, rng )
+ {
+ if(0 == *result || i != *result)
+ return false;
+ ++result;
+ }
+ return 0 == *result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// sequence_equal_byval_c_r
+inline bool sequence_equal_byval_c_r( foreach_const_container_type & rng, char const * result )
+{
+ BOOST_REVERSE_FOREACH( foreach_value_type i, rng )
+ {
+ if(0 == *result || i != *result)
+ return false;
+ ++result;
+ }
+ return 0 == *result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// sequence_equal_byref_n_r
+inline bool sequence_equal_byref_n_r( foreach_container_type & rng, char const * result )
+{
+ BOOST_REVERSE_FOREACH( foreach_reference_type i, rng )
+ {
+ if(0 == *result || i != *result)
+ return false;
+ ++result;
+ }
+ return 0 == *result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// sequence_equal_byref_c_r
+inline bool sequence_equal_byref_c_r( foreach_const_container_type & rng, char const * result )
+{
+ BOOST_REVERSE_FOREACH( foreach_const_reference_type i, rng )
+ {
+ if(0 == *result || i != *result)
+ return false;
+ ++result;
+ }
+ return 0 == *result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// mutate_foreach_byref
+//
+inline void mutate_foreach_byref_r( foreach_container_type & rng )
+{
+ BOOST_REVERSE_FOREACH( foreach_reference_type i, rng )
+ {
+ ++i;
+ }
+}
+
 #endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk