merge [75077] from trunk

[SVN r75078]
This commit is contained in:
Eric Niebler 2011-10-21 03:46:27 +00:00
parent 97f8b9490b
commit 8c0da46fac
6 changed files with 6 additions and 483 deletions

View File

@ -30,15 +30,8 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// Some compilers support rvalue references and auto type deduction.
// With these C++0x features, temporary collections can be bound to
// rvalue references and their lifetime is extended. No copy/move is needed.
#if !defined(BOOST_NO_DECLTYPE) && !defined(BOOST_NO_RVALUE_REFERENCES) \
&& !(BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ <= 4) && !defined(BOOST_INTEL) && \
!defined(BOOST_CLANG))
# define BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
// Some compilers let us detect even const-qualified rvalues at compile-time
#elif !defined(BOOST_NO_RVALUE_REFERENCES) \
#if !defined(BOOST_NO_RVALUE_REFERENCES) \
|| BOOST_WORKAROUND(BOOST_MSVC, >= 1310) && !defined(_PREFAST_) \
|| (BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ <= 5) && !defined(BOOST_INTEL) && \
!defined(BOOST_CLANG)) \
@ -95,16 +88,11 @@
#include <boost/utility/addressof.hpp>
#include <boost/foreach_fwd.hpp>
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# include <boost/type_traits/decay.hpp>
# include <boost/type_traits/remove_const.hpp>
# include <boost/type_traits/remove_cv.hpp>
#endif
#ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION
# include <new>
# include <boost/aligned_storage.hpp>
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/remove_const.hpp>
#endif
namespace boost
@ -701,29 +689,6 @@ begin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminat
}
#endif
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
template<typename T>
inline typename foreach_iterator<typename remove_const<T>::type, is_const<T> >::type
begin(T &col)
{
return boost::begin(col);
}
template<typename T>
inline T *
begin(T *&col)
{
return col;
}
template<typename T>
inline T *
begin(T * const &col)
{
return col;
}
#endif
///////////////////////////////////////////////////////////////////////////////
// end
//
@ -764,33 +729,6 @@ end(auto_any_t, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-s
}
#endif
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
template<typename T>
inline typename foreach_iterator<typename remove_const<T>::type, is_const<T> >::type
end(T &col)
{
return boost::end(col);
}
struct cstr_end_iterator
{
};
template<typename T>
inline cstr_end_iterator
end(T *&col)
{
return cstr_end_iterator();
}
template<typename T>
inline cstr_end_iterator
end(T * const &col)
{
return cstr_end_iterator();
}
#endif
///////////////////////////////////////////////////////////////////////////////
// done
//
@ -809,15 +747,6 @@ inline bool done(auto_any_t cur, auto_any_t, type2type<T *, C> *) // null-termin
}
#endif
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
template<typename Iterator>
inline bool operator !=(Iterator cur, cstr_end_iterator)
{
return *cur != 0;
}
#endif
///////////////////////////////////////////////////////////////////////////////
// next
//
@ -882,35 +811,6 @@ rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-termina
}
#endif
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
template<typename T>
inline typename foreach_reverse_iterator<typename remove_const<T>::type, is_const<T> >::type
rbegin(T &col)
{
return boost::rbegin(col);
}
template<typename T>
inline reverse_iterator<T *>
rbegin(T *&col)
{
T *p = col;
while(0 != *p)
++p;
return reverse_iterator<T *>(p);
}
template<typename T>
inline reverse_iterator<T *>
rbegin(T * const &col)
{
T *p = col;
while(0 != *p)
++p;
return reverse_iterator<T *>(p);
}
#endif
///////////////////////////////////////////////////////////////////////////////
// rend
//
@ -952,29 +852,6 @@ rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminate
}
#endif
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
template<typename T>
inline typename foreach_reverse_iterator<typename remove_const<T>::type, is_const<T> >::type
rend(T &col)
{
return boost::rend(col);
}
template<typename T>
inline reverse_iterator<T *>
rend(T *&col)
{
return reverse_iterator<T *>(col);
}
template<typename T>
inline reverse_iterator<T *>
rend(T * const &col)
{
return reverse_iterator<T *>(col);
}
#endif
///////////////////////////////////////////////////////////////////////////////
// rdone
//
@ -1045,40 +922,10 @@ rderef(auto_any_t cur, type2type<T, C> *)
boost::foreach_detail_::to_ptr(COL) \
, boost_foreach_argument_dependent_lookup_hack_value))
///////////////////////////////////////////////////////////////////////////////
// R-values and const R-values are bound to rvalue references
///////////////////////////////////////////////////////////////////////////////
#if defined(BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING)
# define BOOST_FOREACH_PREAMBLE() \
BOOST_FOREACH_SUPPRESS_WARNINGS()
namespace boost { namespace foreach_detail_
{
template<typename T>
typename remove_cv<typename decay<T>::type>::type decay_copy(T &&);
template<typename T>
T const add_const_if_rvalue(T &&);
}}
# define BOOST_FOREACH_AUTO_OBJECT(NAME, EXPR) \
if (bool BOOST_PP_CAT(NAME, _defined) = false) {} else \
for (decltype(boost::foreach_detail_::decay_copy(EXPR)) NAME = (EXPR); \
!BOOST_PP_CAT(NAME, _defined); BOOST_PP_CAT(NAME, _defined) = true)
// If EXPR is an rvalue, bind it to a const rvalue reference.
# define BOOST_FOREACH_AUTO_REF_REF(NAME, EXPR) \
if (bool BOOST_PP_CAT(NAME, _defined) = false) {} else \
for (decltype(boost::foreach_detail_::add_const_if_rvalue(EXPR)) &&NAME = (EXPR); \
!BOOST_PP_CAT(NAME, _defined); BOOST_PP_CAT(NAME, _defined) = true)
#elif defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION)
#if defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION)
///////////////////////////////////////////////////////////////////////////////
// R-values and const R-values supported here with zero runtime overhead
///////////////////////////////////////////////////////////////////////////////
# define BOOST_FOREACH_PREAMBLE() \
BOOST_FOREACH_SUPPRESS_WARNINGS()
// No variable is needed to track the rvalue-ness of the collection expression
# define BOOST_FOREACH_PREAMBLE() \
@ -1245,28 +1092,7 @@ namespace boost { namespace foreach_detail_
// BOOST_FOREACH(i, int_list)
// { ... }
//
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# define BOOST_FOREACH(VAR, COL) \
BOOST_FOREACH_PREAMBLE() \
BOOST_FOREACH_AUTO_REF_REF( \
BOOST_FOREACH_ID(_foreach_col) \
, COL) \
BOOST_FOREACH_AUTO_OBJECT( \
BOOST_FOREACH_ID(_foreach_cur) \
, boost::foreach_detail_::begin(BOOST_FOREACH_ID(_foreach_col))) \
BOOST_FOREACH_AUTO_OBJECT( \
BOOST_FOREACH_ID(_foreach_end) \
, boost::foreach_detail_::end(BOOST_FOREACH_ID(_foreach_col))) \
for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \
BOOST_FOREACH_ID(_foreach_continue) \
&& BOOST_FOREACH_ID(_foreach_cur) != BOOST_FOREACH_ID(_foreach_end); \
BOOST_FOREACH_ID(_foreach_continue) \
? (void)++BOOST_FOREACH_ID(_foreach_cur) : (void)0) \
if ( (BOOST_FOREACH_ID(_foreach_continue) = false) ) {} else \
for (VAR = *BOOST_FOREACH_ID(_foreach_cur); \
!BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
#else
# define BOOST_FOREACH(VAR, COL) \
#define BOOST_FOREACH(VAR, COL) \
BOOST_FOREACH_PREAMBLE() \
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \
@ -1276,7 +1102,6 @@ namespace boost { namespace foreach_detail_
BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \
if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
for (VAR = BOOST_FOREACH_DEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
#endif
///////////////////////////////////////////////////////////////////////////////
// BOOST_REVERSE_FOREACH
@ -1285,28 +1110,7 @@ namespace boost { namespace foreach_detail_
// all other respects, BOOST_REVERSE_FOREACH is like
// BOOST_FOREACH.
//
#ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# define BOOST_REVERSE_FOREACH(VAR, COL) \
BOOST_FOREACH_PREAMBLE() \
BOOST_FOREACH_AUTO_REF_REF( \
BOOST_FOREACH_ID(_foreach_col) \
, COL) \
BOOST_FOREACH_AUTO_OBJECT( \
BOOST_FOREACH_ID(_foreach_cur) \
, boost::foreach_detail_::rbegin(BOOST_FOREACH_ID(_foreach_col))) \
BOOST_FOREACH_AUTO_OBJECT( \
BOOST_FOREACH_ID(_foreach_end) \
, boost::foreach_detail_::rend(BOOST_FOREACH_ID(_foreach_col))) \
for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \
BOOST_FOREACH_ID(_foreach_continue) \
&& BOOST_FOREACH_ID(_foreach_cur) != BOOST_FOREACH_ID(_foreach_end); \
BOOST_FOREACH_ID(_foreach_continue) \
? (void)++BOOST_FOREACH_ID(_foreach_cur) : (void)0) \
if ( (BOOST_FOREACH_ID(_foreach_continue) = false) ) {} else \
for (VAR = *BOOST_FOREACH_ID(_foreach_cur); \
!BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
#else
# define BOOST_REVERSE_FOREACH(VAR, COL) \
#define BOOST_REVERSE_FOREACH(VAR, COL) \
BOOST_FOREACH_PREAMBLE() \
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_RBEGIN(COL)) {} else \
@ -1316,6 +1120,5 @@ namespace boost { namespace foreach_detail_
BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_RNEXT(COL) : (void)0) \
if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
for (VAR = BOOST_FOREACH_RDEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)
#endif
#endif

View File

@ -5,7 +5,7 @@
# bring in rules for testing
import testing ;
project : requirements <toolset>msvc:<asynch-exceptions>on <toolset>gcc:<cxxflags>-Wconversion ;
project : requirements <toolset>msvc:<asynch-exceptions>on ;
test-suite "foreach"
: [ run stl_byval.cpp ]
@ -32,9 +32,5 @@ test-suite "foreach"
[ run rvalue_nonconst_r.cpp ]
[ run dependent_type.cpp ]
[ run misc.cpp ]
[ run noncopyable_rvalue_const.cpp ]
[ run noncopyable_rvalue_nonconst.cpp ]
[ run noncopyable_rvalue_const_r.cpp ]
[ run noncopyable_rvalue_nonconst_r.cpp ]
[ compile noncopyable.cpp ]
;

View File

@ -1,70 +0,0 @@
// (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 <boost/test/minimal.hpp>
#include <boost/foreach.hpp>
#ifndef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# error Expected failure : non-copyable rvalues disallowed
#else
class my_container
{
public:
my_container()
{
array_[0] = 1;
array_[1] = 2;
array_[2] = 3;
array_[3] = 4;
array_[4] = 5;
}
typedef int* iterator;
typedef int const* const_iterator;
iterator begin() { return array_; }
const_iterator begin() const { return array_; }
iterator end() { return array_ + 5; }
const_iterator end() const { return array_ + 5; }
private:
int array_[5];
// non-copyable
my_container(my_container const &);
my_container &operator =(my_container const &);
// non-movable
my_container(my_container &&);
my_container &operator =(my_container &&);
};
typedef my_container const const_my_container;
///////////////////////////////////////////////////////////////////////////////
// test_main
//
int test_main( int, char*[] )
{
int counter = 0;
BOOST_FOREACH(int i, const_my_container())
{
counter += i;
}
BOOST_CHECK(15 == counter);
return 0;
}
#endif

View File

@ -1,70 +0,0 @@
// (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 <boost/test/minimal.hpp>
#include <boost/foreach.hpp>
#ifndef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# error Expected failure : non-copyable rvalues disallowed
#else
class my_container
{
public:
my_container()
{
array_[0] = 1;
array_[1] = 2;
array_[2] = 3;
array_[3] = 4;
array_[4] = 5;
}
typedef int* iterator;
typedef int const* const_iterator;
iterator begin() { return array_; }
const_iterator begin() const { return array_; }
iterator end() { return array_ + 5; }
const_iterator end() const { return array_ + 5; }
private:
int array_[5];
// non-copyable
my_container(my_container const &);
my_container &operator =(my_container const &);
// non-movable
my_container(my_container &&);
my_container &operator =(my_container &&);
};
typedef my_container const const_my_container;
///////////////////////////////////////////////////////////////////////////////
// test_main
//
int test_main( int, char*[] )
{
int counter = 0;
BOOST_REVERSE_FOREACH(int i, const_my_container())
{
counter += i;
}
BOOST_CHECK(15 == counter);
return 0;
}
#endif

View File

@ -1,68 +0,0 @@
// (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 <boost/test/minimal.hpp>
#include <boost/foreach.hpp>
#ifndef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# error Expected failure : non-copyable rvalues disallowed
#else
class my_container
{
public:
my_container()
{
array_[0] = 1;
array_[1] = 2;
array_[2] = 3;
array_[3] = 4;
array_[4] = 5;
}
typedef int* iterator;
typedef int const* const_iterator;
iterator begin() { return array_; }
const_iterator begin() const { return array_; }
iterator end() { return array_ + 5; }
const_iterator end() const { return array_ + 5; }
private:
int array_[5];
// non-copyable
my_container(my_container const &);
my_container &operator =(my_container const &);
// non-movable
my_container(my_container &&);
my_container &operator =(my_container &&);
};
///////////////////////////////////////////////////////////////////////////////
// test_main
//
int test_main( int, char*[] )
{
int counter = 0;
BOOST_REVERSE_FOREACH(int i, my_container())
{
counter += i;
}
BOOST_CHECK(15 == counter);
return 0;
}
#endif

View File

@ -1,68 +0,0 @@
// (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 <boost/test/minimal.hpp>
#include <boost/foreach.hpp>
#ifndef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING
# error Expected failure : non-copyable rvalues disallowed
#else
class my_container
{
public:
my_container()
{
array_[0] = 1;
array_[1] = 2;
array_[2] = 3;
array_[3] = 4;
array_[4] = 5;
}
typedef int* iterator;
typedef int const* const_iterator;
iterator begin() { return array_; }
const_iterator begin() const { return array_; }
iterator end() { return array_ + 5; }
const_iterator end() const { return array_ + 5; }
private:
int array_[5];
// non-copyable
my_container(my_container const &);
my_container &operator =(my_container const &);
// non-movable
my_container(my_container &&);
my_container &operator =(my_container &&);
};
///////////////////////////////////////////////////////////////////////////////
// test_main
//
int test_main( int, char*[] )
{
int counter = 0;
BOOST_REVERSE_FOREACH(int i, my_container())
{
counter += i;
}
BOOST_CHECK(15 == counter);
return 0;
}
#endif