|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r81421 - trunk/boost/heap/detail
From: tim_at_[hidden]
Date: 2012-11-19 07:16:32
Author: timblechmann
Date: 2012-11-19 07:16:31 EST (Mon, 19 Nov 2012)
New Revision: 81421
URL: http://svn.boost.org/trac/boost/changeset/81421
Log:
heap: workaround for msvc lookup bug
attempt to fix #7358
Text files modified:
trunk/boost/heap/detail/mutable_heap.hpp | 2
trunk/boost/heap/detail/stable_heap.hpp | 102 +++++++++++++++++++++++++++++++++------
2 files changed, 86 insertions(+), 18 deletions(-)
Modified: trunk/boost/heap/detail/mutable_heap.hpp
==============================================================================
--- trunk/boost/heap/detail/mutable_heap.hpp (original)
+++ trunk/boost/heap/detail/mutable_heap.hpp 2012-11-19 07:16:31 EST (Mon, 19 Nov 2012)
@@ -382,7 +382,7 @@
{
list_iterator it = handle.iterator;
value_type const & current_value = it->first;
- value_compare const & cmp = q_;
+ value_compare const & cmp = q_.value_comp();
if (cmp(v, current_value))
decrease(handle, v);
else
Modified: trunk/boost/heap/detail/stable_heap.hpp
==============================================================================
--- trunk/boost/heap/detail/stable_heap.hpp (original)
+++ trunk/boost/heap/detail/stable_heap.hpp 2012-11-19 07:16:31 EST (Mon, 19 Nov 2012)
@@ -24,7 +24,6 @@
namespace heap {
namespace detail {
-
template<bool ConstantSize, class SizeType>
struct size_holder
{
@@ -133,6 +132,8 @@
{}
};
+// note: MSVC does not implement lookup correctly, we therefore have to place the Cmp object as member inside the
+// struct. of course, this prevents EBO and significantly reduces the readability of this code
template <typename T,
typename Cmp,
bool constant_time_size,
@@ -140,7 +141,9 @@
bool stable = false
>
struct heap_base:
+#ifndef BOOST_MSVC
Cmp,
+#endif
size_holder<constant_time_size, size_t>
{
typedef StabilityCounterType stability_counter_type;
@@ -151,31 +154,47 @@
typedef Cmp internal_compare;
static const bool is_stable = stable;
+#ifdef BOOST_MSVC
+ Cmp cmp_;
+#endif
+
heap_base (Cmp const & cmp = Cmp()):
+#ifndef BOOST_MSVC
Cmp(cmp)
+#else
+ cmp_(cmp)
+#endif
{}
#ifdef BOOST_HAS_RVALUE_REFS
heap_base(heap_base && rhs):
+#ifndef BOOST_MSVC
Cmp(std::move(static_cast<Cmp&>(rhs))),
+#else
+ cmp_(std::move(rhs.cmp_)),
+#endif
size_holder_type(std::move(static_cast<size_holder_type&>(rhs)))
{}
heap_base(heap_base const & rhs):
+#ifndef BOOST_MSVC
Cmp(static_cast<Cmp const &>(rhs)),
+#else
+ cmp_(rhs.value_comp()),
+#endif
size_holder_type(static_cast<size_holder_type const &>(rhs))
{}
heap_base & operator=(heap_base && rhs)
{
- Cmp::operator=(std::move(static_cast<Cmp&>(rhs)));
+ value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
return *this;
}
heap_base & operator=(heap_base const & rhs)
{
- Cmp::operator=(static_cast<Cmp const &>(rhs));
+ value_comp_ref().operator=(rhs.value_comp());
size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
return *this;
}
@@ -183,7 +202,7 @@
bool operator()(internal_type const & lhs, internal_type const & rhs) const
{
- return Cmp::operator()(lhs, rhs);
+ return value_comp().operator()(lhs, rhs);
}
internal_type make_node(T const & val)
@@ -210,17 +229,21 @@
Cmp const & value_comp(void) const
{
+#ifndef BOOST_MSVC
return *this;
+#else
+ return cmp_;
+#endif
}
Cmp const & get_internal_cmp(void) const
{
- return *this;
+ return value_comp();
}
void swap(heap_base & rhs)
{
- std::swap(static_cast<Cmp&>(*this), static_cast<Cmp&>(rhs));
+ std::swap(value_comp_ref(), rhs.value_comp_ref());
size_holder<constant_time_size, size_t>::swap(rhs);
}
@@ -234,15 +257,28 @@
template <typename Heap1, typename Heap2>
friend struct heap_merge_emulate;
+
+private:
+ Cmp & value_comp_ref(void)
+ {
+#ifndef BOOST_MSVC
+ return *this;
+#else
+ return cmp_;
+#endif
+ }
};
+
template <typename T,
typename Cmp,
bool constant_time_size,
typename StabilityCounterType
>
struct heap_base<T, Cmp, constant_time_size, StabilityCounterType, true>:
+#ifndef BOOST_MSVC
Cmp,
+#endif
size_holder<constant_time_size, size_t>
{
typedef StabilityCounterType stability_counter_type;
@@ -251,26 +287,43 @@
typedef size_holder<constant_time_size, size_t> size_holder_type;
typedef Cmp value_compare;
+#ifdef BOOST_MSVC
+ Cmp cmp_;
+#endif
+
heap_base (Cmp const & cmp = Cmp()):
- Cmp(cmp), counter_(0)
+#ifndef BOOST_MSVC
+ Cmp(cmp),
+#else
+ cmp_(cmp),
+#endif
+ counter_(0)
{}
#ifdef BOOST_HAS_RVALUE_REFS
heap_base(heap_base && rhs):
+#ifndef BOOST_MSVC
Cmp(std::move(static_cast<Cmp&>(rhs))),
+#else
+ cmp_(std::move(rhs.cmp_)),
+#endif
size_holder_type(std::move(static_cast<size_holder_type&>(rhs))), counter_(rhs.counter_)
{
rhs.counter_ = 0;
}
- heap_base(heap_base & rhs):
- Cmp(static_cast<Cmp&>(rhs)),
- size_holder_type(static_cast<size_holder_type&>(rhs)), counter_(rhs.counter_)
+ heap_base(heap_base const & rhs):
+#ifndef BOOST_MSVC
+ Cmp(static_cast<Cmp const&>(rhs)),
+#else
+ cmp_(rhs.value_comp()),
+#endif
+ size_holder_type(static_cast<size_holder_type const &>(rhs)), counter_(rhs.counter_)
{}
heap_base & operator=(heap_base && rhs)
{
- Cmp::operator=(std::move(static_cast<Cmp&>(rhs)));
+ value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
counter_ = rhs.counter_;
@@ -280,24 +333,22 @@
heap_base & operator=(heap_base const & rhs)
{
- Cmp::operator=(static_cast<Cmp const &>(rhs));
+ value_comp_ref().operator=(rhs.value_comp());
size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
counter_ = rhs.counter_;
return *this;
}
-
#endif
bool operator()(internal_type const & lhs, internal_type const & rhs) const
{
- internal_compare cmp(get_internal_cmp());
- return cmp(lhs, rhs);
+ return get_internal_cmp()(lhs, rhs);
}
bool operator()(T const & lhs, T const & rhs) const
{
- return Cmp::operator()(lhs, rhs);
+ return value_comp()(lhs, rhs);
}
internal_type make_node(T const & val)
@@ -331,7 +382,11 @@
Cmp const & value_comp(void) const
{
+#ifndef BOOST_MSVC
return *this;
+#else
+ return cmp_;
+#endif
}
struct internal_compare:
@@ -355,12 +410,16 @@
internal_compare get_internal_cmp(void) const
{
- return internal_compare(*this);
+ return internal_compare(value_comp());
}
void swap(heap_base & rhs)
{
+#ifndef BOOST_MSVC
std::swap(static_cast<Cmp&>(*this), static_cast<Cmp&>(rhs));
+#else
+ std::swap(cmp_, rhs.cmp_);
+#endif
std::swap(counter_, rhs.counter_);
size_holder<constant_time_size, size_t>::swap(rhs);
}
@@ -379,6 +438,15 @@
friend struct heap_merge_emulate;
private:
+ Cmp & value_comp_ref(void)
+ {
+#ifndef BOOST_MSVC
+ return *this;
+#else
+ return cmp_;
+#endif
+ }
+
stability_counter_type counter_;
};
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