|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r74101 - in branches/release: boost/unordered boost/unordered/detail libs/unordered libs/unordered/test/helpers libs/unordered/test/objects libs/unordered/test/unordered
From: dnljms_at_[hidden]
Date: 2011-08-28 07:26:41
Author: danieljames
Date: 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
New Revision: 74101
URL: http://svn.boost.org/trac/boost/changeset/74101
Log:
Unordered: Merge from trunk.
Portability fixes, and fix some issues with constructing std::pair.
Added:
branches/release/libs/unordered/test/unordered/allocator_traits.cpp
- copied unchanged from r74100, /trunk/libs/unordered/test/unordered/allocator_traits.cpp
Properties modified:
branches/release/boost/unordered/ (props changed)
branches/release/libs/unordered/ (props changed)
Text files modified:
branches/release/boost/unordered/detail/allocator_helpers.hpp | 121 +++++++++++++++++-------------
branches/release/boost/unordered/detail/buckets.hpp | 154 ++++++++++++++++++++++++++++++++-------
branches/release/boost/unordered/detail/table.hpp | 8 +
branches/release/libs/unordered/test/helpers/memory.hpp | 9 +
branches/release/libs/unordered/test/objects/cxx11_allocator.hpp | 17 +++-
branches/release/libs/unordered/test/objects/test.hpp | 4
branches/release/libs/unordered/test/unordered/Jamfile.v2 | 1
branches/release/libs/unordered/test/unordered/insert_tests.cpp | 79 ++++++++++++++++++++
branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp | 5 +
9 files changed, 304 insertions(+), 94 deletions(-)
Modified: branches/release/boost/unordered/detail/allocator_helpers.hpp
==============================================================================
--- branches/release/boost/unordered/detail/allocator_helpers.hpp (original)
+++ branches/release/boost/unordered/detail/allocator_helpers.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -5,8 +5,8 @@
// Distributed under 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)
//
-// Written by Daniel James using some code from Pablo Halpern's
-// allocator traits implementation.
+// Allocator traits written by Daniel James based on Pablo Halpern's
+// implementation.
#ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
#define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
@@ -18,6 +18,7 @@
#include <boost/config.hpp>
#include <boost/detail/select_type.hpp>
#include <boost/utility/enable_if.hpp>
+#include <boost/preprocessor/cat.hpp>
#if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
&& !defined(__BORLANDC__)
@@ -81,38 +82,39 @@
};
# endif
- struct convertible_from_anything
- {
- template<typename T> convertible_from_anything(T const&);
- };
+ template <typename T> T& make();
+ struct choice9 { typedef char (&type)[9]; };
+ struct choice8 : choice9 { typedef char (&type)[8]; };
+ struct choice7 : choice8 { typedef char (&type)[7]; };
+ struct choice6 : choice7 { typedef char (&type)[6]; };
+ struct choice5 : choice6 { typedef char (&type)[5]; };
+ struct choice4 : choice5 { typedef char (&type)[4]; };
+ struct choice3 : choice4 { typedef char (&type)[3]; };
+ struct choice2 : choice3 { typedef char (&type)[2]; };
+ struct choice1 : choice2 { typedef char (&type)[1]; };
+ choice1 choose();
- typedef char (&no_type)[1];
- typedef char (&yes_type)[2];
-
- template <typename T> struct sfinae {
- typedef yes_type type;
- };
-
- // Infrastructure for providing a default type for Tp::tname if absent.
#define BOOST_DEFAULT_TYPE_TMPLT(tname) \
template <typename Tp, typename Default> \
struct default_type_ ## tname { \
- template <typename T> \
- static BOOST_DEDUCED_TYPENAME sfinae< \
- BOOST_DEDUCED_TYPENAME T::tname>::type test(int); \
- template <typename T> \
- static no_type test(long); \
\
- enum { value = sizeof(test<Tp>(0)) == sizeof(yes_type) }; \
+ template <typename X> \
+ static choice1::type test(choice1, \
+ BOOST_DEDUCED_TYPENAME X::tname* = 0); \
+ \
+ template <typename X> \
+ static choice2::type test(choice2, void* = 0); \
\
struct DefaultWrap { typedef Default tname; }; \
\
+ enum { value = (1 == sizeof(test<Tp>(choose()))) }; \
+ \
typedef BOOST_DEDUCED_TYPENAME \
boost::detail::if_true<value>:: \
BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap> \
::type::tname type; \
}
-
+
#define BOOST_DEFAULT_TYPE(T,tname, arg) \
BOOST_DEDUCED_TYPENAME default_type_ ## tname<T, arg>::type
@@ -127,47 +129,62 @@
BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
#if !defined(BOOST_NO_SFINAE_EXPR) || BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
- // Specialization is only needed for Visual C++. Without it SFINAE doesn't
- // kick in.
- template <unsigned int>
- struct expr_sfinae;
-
- template <>
- struct expr_sfinae<sizeof(yes_type)> {
- typedef yes_type type;
- };
-
+
+ template <typename T, unsigned int> struct expr_test;
+ template <typename T> struct expr_test<T, sizeof(char)> : T {};
+ template <typename U> static char for_expr_test(U const&);
+
+#define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \
+ template <typename U> \
+ static typename expr_test< \
+ BOOST_PP_CAT(choice, result), \
+ sizeof(for_expr_test(((expression), 0)))>::type test( \
+ BOOST_PP_CAT(choice, count))
+
+#define BOOST_UNORDERED_DEFAULT_EXPRESSION(count, result) \
+ template <typename U> \
+ static BOOST_PP_CAT(choice, result)::type test( \
+ BOOST_PP_CAT(choice, count))
+
template <typename T>
struct has_select_on_container_copy_construction
{
- // This needs to be a template for Visual C++.
- template <typename T2>
- static yes_type to_yes_type(const T2&);
-
- template <typename T2>
- static typename expr_sfinae<sizeof(to_yes_type(
- ((T2 const*)0)->select_on_container_copy_construction()
- ))>::type check(T2*);
-
- static no_type check(void*);
+ BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, make<U const>().select_on_container_copy_construction());
+ BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2);
- enum { value = sizeof(check((T*) 0)) == sizeof(yes_type) };
+ enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
};
+
#else
+
+ template <typename T> struct identity { typedef T type; };
+
+#define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member) \
+ \
+ typedef typename identity<member>::type BOOST_PP_CAT(check, count); \
+ \
+ template <BOOST_PP_CAT(check, count) e> \
+ struct BOOST_PP_CAT(test, count) { \
+ typedef void* type; \
+ }; \
+ \
+ template <class U> static BOOST_PP_CAT(choice, result)::type \
+ test(BOOST_PP_CAT(choice, count), \
+ typename BOOST_PP_CAT(test, count)< \
+ &U::name>::type = 0)
+
+#define BOOST_UNORDERED_DEFAULT_MEMBER(count, result) \
+ template <class U> static BOOST_PP_CAT(choice, result)::type \
+ test(BOOST_PP_CAT(choice, count), void* = 0)
+
+
template <typename T>
struct has_select_on_container_copy_construction
{
- typedef T (T::*SelectFunc)() const;
-
- template <SelectFunc e> struct sfinae { typedef yes_type type; };
-
- template <class U>
- static typename sfinae<&U::select_on_container_copy_construction>::type
- test(int);
- template <class U>
- static no_type test(...);
+ BOOST_UNORDERED_CHECK_MEMBER(1, 1, select_on_container_copy_construction, T (T::*)() const);
+ BOOST_UNORDERED_DEFAULT_MEMBER(2, 2);
- enum { value = sizeof(test<T>(1)) == sizeof(yes_type) };
+ enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
};
#endif
Modified: branches/release/boost/unordered/detail/buckets.hpp
==============================================================================
--- branches/release/boost/unordered/detail/buckets.hpp (original)
+++ branches/release/boost/unordered/detail/buckets.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -517,44 +517,139 @@
////////////////////////////////////////////////////////////////////////////
// Node Constructors
+ template <typename T, typename Arg1 = void>
+ struct emulated_pair_constructor
+ {
+ enum { value = false };
+ };
+
+ template <typename A, typename B>
+ struct emulated_pair_constructor<std::pair<A, B>, void>
+ {
+ enum { value = true };
+ };
+
+ template <typename A, typename B, typename Value>
+ struct emulated_pair_constructor<std::pair<A, B>, Value>
+ {
+ static choice1::type check(choice1, std::pair<A, B> const&);
+ static choice2::type check(choice2, A const&);
+
+ enum { value = sizeof(check(choose(), make<Value>())) - 1 };
+ };
+
+ template <class T>
+ inline void construct_impl(void* address)
+ {
+ new(address) T();
+ }
+
#if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
- template <class T, class... Args>
- inline void construct_impl(T*, void* address, Args&&... args)
+ template <class T, class Arg1>
+ inline void construct_impl(
+ typename boost::disable_if<emulated_pair_constructor<T, Arg1>,
+ void*>::type address,
+ Arg1&& a1)
+ {
+ new(address) T(std::forward<Arg1>(a1));
+ }
+
+ template <class T, class Arg1>
+ inline void construct_impl(
+ typename boost::enable_if<emulated_pair_constructor<T, Arg1>,
+ void*>::type address,
+ Arg1&& a1)
+ {
+ new(address) T(std::forward<Arg1>(a1), typename T::second_type());
+ }
+
+ template <class T, class Arg1, class Arg2>
+ inline void construct_impl(void* address, Arg1&& a1, Arg2&& a2)
{
- new(address) T(std::forward<Args>(args)...);
+ new(address) T(std::forward<Arg1>(a1), std::forward<Arg2>(a2));
+ }
+
+ template <class T, class Arg1, class Arg2, class... Args>
+ inline typename boost::disable_if<emulated_pair_constructor<T>, void>::type
+ construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
+ {
+ new(address) T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Args>(args)...);
+ }
+
+ template <class T, class Arg1, class Arg2, class... Args>
+ inline typename boost::enable_if<emulated_pair_constructor<T>, void>::type
+ construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
+ {
+ new(address) T(std::forward<Arg1>(arg1),
+ typename T::second_type(
+ std::forward<Arg2>(arg2), std::forward<Args>(args)...));
}
#else
-#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
- template < \
- class T, \
- BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
- > \
- inline void construct_impl( \
- T*, void* address, \
- BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params) \
- ) \
- { \
- new(address) T( \
- BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
- } \
- \
- template <class First, class Second, class Key, \
- BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
- > \
- inline void construct_impl( \
- std::pair<First, Second>*, void* address, \
- Key const& k, BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
- { \
- new(address) std::pair<First, Second>(k, \
- Second(BOOST_UNORDERED_CALL_PARAMS(z, num_params))); \
+ template <class T, class Arg1>
+ inline BOOST_DEDUCED_TYPENAME boost::disable_if<emulated_pair_constructor<T, Arg1>, void>::type
+ construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
+ {
+ new(address) T(boost::forward<Arg1>(a1));
+ }
+
+ template <class T, class Arg1>
+ inline BOOST_DEDUCED_TYPENAME boost::enable_if<emulated_pair_constructor<T, Arg1>, void>::type
+ construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
+ {
+ new(address) T(
+ boost::forward<Arg1>(a1),
+ BOOST_DEDUCED_TYPENAME T::second_type()
+ );
}
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
+ template <class T, class Arg1, class Arg2>
+ inline void construct_impl(void* address,
+ BOOST_FWD_REF(Arg1) a1, BOOST_FWD_REF(Arg2) a2)
+ {
+ new(address) T(boost::forward<Arg1>(a1), boost::forward<Arg2>(a2));
+ }
+
+#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
+ template < \
+ class T, \
+ BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
+ > \
+ inline void construct_impl( \
+ BOOST_DEDUCED_TYPENAME \
+ boost::disable_if<emulated_pair_constructor<T>, void*>::type \
+ address, \
+ BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params) \
+ ) \
+ { \
+ new(address) T( \
+ BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO(3, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_CONSTRUCT_IMPL, _)
+#define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _) \
+ template <class T, class Key, \
+ BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params) \
+ > \
+ inline void construct_impl( \
+ BOOST_DEDUCED_TYPENAME \
+ boost::enable_if<emulated_pair_constructor<T>, void*>::type \
+ address, \
+ Key const& k, BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
+ { \
+ new(address) T(k, \
+ BOOST_DEDUCED_TYPENAME \
+ T::second_type(BOOST_UNORDERED_CALL_PARAMS(z, num_params))); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO(2, BOOST_UNORDERED_EMPLACE_LIMIT,
+ BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL, _)
+
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
#endif
@@ -594,7 +689,7 @@
void construct(Args&&... args)
{
construct_preamble();
- construct_impl((value_type*) 0, node_->address(),
+ construct_impl<value_type>(node_->address(),
std::forward<Args>(args)...);
value_constructed_ = true;
}
@@ -609,8 +704,7 @@
) \
{ \
construct_preamble(); \
- construct_impl( \
- (value_type*) 0, node_->address(), \
+ construct_impl<value_type>(node_->address(), \
BOOST_UNORDERED_CALL_PARAMS(z, num_params) \
); \
value_constructed_ = true; \
Modified: branches/release/boost/unordered/detail/table.hpp
==============================================================================
--- branches/release/boost/unordered/detail/table.hpp (original)
+++ branches/release/boost/unordered/detail/table.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -167,7 +167,9 @@
//
// Or from rehash post-condition:
// count > size / mlf_
- return next_prime(double_to_size_t(floor(size / (double) mlf_)) + 1);
+ return next_prime(double_to_size_t(floor(
+ static_cast<double>(size) /
+ static_cast<double>(mlf_))) + 1);
}
////////////////////////////////////////////////////////////////////////
@@ -451,7 +453,9 @@
else {
// no throw:
min_buckets = next_prime((std::max)(min_buckets,
- double_to_size_t(floor(this->size_ / (double) mlf_)) + 1));
+ double_to_size_t(floor(
+ static_cast<double>(this->size_) /
+ static_cast<double>(mlf_))) + 1));
if(min_buckets != this->bucket_count_) {
this->rehash_impl(min_buckets);
this->max_load_ = calculate_max_load();
Modified: branches/release/libs/unordered/test/helpers/memory.hpp
==============================================================================
--- branches/release/libs/unordered/test/helpers/memory.hpp (original)
+++ branches/release/libs/unordered/test/helpers/memory.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -194,8 +194,13 @@
enum { value = false };
};
- template <typename Alloc>
- int selected_count(Alloc const&)
+ struct convert_from_anything
+ {
+ template <typename T>
+ convert_from_anything(T const&) {}
+ };
+
+ int selected_count(convert_from_anything)
{
return 0;
}
Modified: branches/release/libs/unordered/test/objects/cxx11_allocator.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/cxx11_allocator.hpp (original)
+++ branches/release/libs/unordered/test/objects/cxx11_allocator.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -186,9 +186,14 @@
};
template <typename T, typename Flags = propagate_swap,
- bool SelectCopy = Flags::is_select_on_copy ? true : false>
- struct cxx11_allocator :
- public cxx11_allocator_base<T>,
+ typename Enable = void>
+ struct cxx11_allocator;
+
+ template <typename T, typename Flags>
+ struct cxx11_allocator<
+ T, Flags,
+ typename boost::disable_if_c<Flags::is_select_on_copy>::type
+ > : public cxx11_allocator_base<T>,
public swap_allocator_base<Flags>,
public assign_allocator_base<Flags>,
public move_allocator_base<Flags>,
@@ -228,8 +233,10 @@
};
template <typename T, typename Flags>
- struct cxx11_allocator<T, Flags, true> :
- public cxx11_allocator_base<T>,
+ struct cxx11_allocator<
+ T, Flags,
+ typename boost::enable_if_c<Flags::is_select_on_copy>::type
+ > : public cxx11_allocator_base<T>,
public swap_allocator_base<Flags>,
public assign_allocator_base<Flags>,
public move_allocator_base<Flags>,
Modified: branches/release/libs/unordered/test/objects/test.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/test.hpp (original)
+++ branches/release/libs/unordered/test/objects/test.hpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -26,7 +26,7 @@
object generate(object const*);
implicitly_convertible generate(implicitly_convertible const*);
- class object : globally_counted_object
+ class object : private globally_counted_object
{
friend class hash;
friend class equal_to;
@@ -64,7 +64,7 @@
}
};
- class implicitly_convertible : globally_counted_object
+ class implicitly_convertible : private globally_counted_object
{
int tag1_, tag2_;
public:
Modified: branches/release/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/release/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ branches/release/libs/unordered/test/unordered/Jamfile.v2 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -22,6 +22,7 @@
:
[ run fwd_set_test.cpp ]
[ run fwd_map_test.cpp ]
+ [ run allocator_traits.cpp ]
[ run compile_set.cpp ]
[ run compile_map.cpp ]
[ run link_test_1.cpp link_test_2.cpp ]
Modified: branches/release/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/insert_tests.cpp (original)
+++ branches/release/libs/unordered/test/unordered/insert_tests.cpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -514,6 +514,85 @@
#endif
+struct overloaded_constructor
+{
+ overloaded_constructor(int x1 = 1, int x2 = 2, int x3 = 3, int x4 = 4)
+ : x1(x1), x2(x2), x3(x3), x4(x4) {}
+
+ int x1, x2, x3, x4;
+
+ bool operator==(overloaded_constructor const& rhs) const
+ {
+ return x1 == rhs.x1 && x2 == rhs.x2 && x3 == rhs.x3 && x4 == rhs.x4;
+ }
+
+ friend std::size_t hash_value(overloaded_constructor const& x)
+ {
+ std::size_t hash = 0;
+ boost::hash_combine(hash, x.x1);
+ boost::hash_combine(hash, x.x2);
+ boost::hash_combine(hash, x.x3);
+ boost::hash_combine(hash, x.x4);
+ return hash;
+ }
+};
+
+// This will actually be deprecated pretty soon.
+
+UNORDERED_AUTO_TEST(map_emplace_test)
+{
+ boost::unordered_map<int, overloaded_constructor> x;
+
+ x.emplace();
+ BOOST_TEST(x.find(0) != x.end() &&
+ x.find(0)->second == overloaded_constructor());
+
+ x.emplace(1);
+ BOOST_TEST(x.find(1) != x.end() &&
+ x.find(1)->second == overloaded_constructor());
+
+ x.emplace(2, 3);
+ BOOST_TEST(x.find(2) != x.end() &&
+ x.find(2)->second == overloaded_constructor(3));
+
+ x.emplace(4, 5, 6);
+ BOOST_TEST(x.find(4) != x.end() &&
+ x.find(4)->second == overloaded_constructor(5, 6));
+
+ x.emplace(7, 8, 9, 10);
+ BOOST_TEST(x.find(7) != x.end() &&
+ x.find(7)->second == overloaded_constructor(8, 9, 10));
+}
+
+UNORDERED_AUTO_TEST(set_emplace_test)
+{
+ boost::unordered_set<overloaded_constructor> x;
+ overloaded_constructor check;
+
+ x.emplace();
+ BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+ x.clear();
+ x.emplace(1);
+ check = overloaded_constructor(1);
+ BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+ x.clear();
+ x.emplace(2, 3);
+ check = overloaded_constructor(2, 3);
+ BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+ x.clear();
+ x.emplace(4, 5, 6);
+ check = overloaded_constructor(4, 5, 6);
+ BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+ x.clear();
+ x.emplace(7, 8, 9, 10);
+ check = overloaded_constructor(7, 8, 9, 10);
+ BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+}
+
}
RUN_TESTS()
Modified: branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp (original)
+++ branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -341,7 +341,10 @@
x.emplace(source<std::pair<count_copies, count_copies> >());
COPY_COUNT(2); MOVE_COUNT(source_pair_cost);
-#if !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
+#if (defined(__GNUC__) && __GNUC__ > 4) || \
+ (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 2) || \
+ (defined(BOOST_MSVC) && BOOST_MSVC >= 1600 ) || \
+ (!defined(__GNUC__) && !defined(BOOST_MSVC))
count_copies part;
reset();
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
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