summaryrefslogtreecommitdiff
path: root/boost/functional
diff options
context:
space:
mode:
Diffstat (limited to 'boost/functional')
-rw-r--r--boost/functional/forward_adapter.hpp33
-rw-r--r--boost/functional/hash/hash.hpp8
-rw-r--r--boost/functional/lightweight_forward_adapter.hpp33
3 files changed, 67 insertions, 7 deletions
diff --git a/boost/functional/forward_adapter.hpp b/boost/functional/forward_adapter.hpp
index 796abd2bc4..6023fc2ae5 100644
--- a/boost/functional/forward_adapter.hpp
+++ b/boost/functional/forward_adapter.hpp
@@ -144,8 +144,30 @@ namespace boost
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
- template< class MD, class F, class FC >
- struct forward_adapter_impl<MD,F,FC,0,0>
+ // WHen operator()() doesn't have any parameters, it can't
+ // be templatized and can't use SFINAE, so intead use class
+ // template parameter SFINAE to decide whether to instantiate it.
+
+ template <typename T, typename R = void>
+ struct forward_adapter_sfinae
+ {
+ typedef T type;
+ };
+
+ // This is the fallback for when there isn't an operator()(),
+ // need to create an operator() that will never instantiate
+ // so that using parent::operator() will work okay.
+ template< class MD, class F, class FC, class Enable = void>
+ struct forward_adapter_impl_zero
+ {
+ template <typename T> struct never_instantiate {};
+ template <typename T>
+ typename never_instantiate<T>::type operator()(T) const {}
+ };
+
+ template< class MD, class F, class FC>
+ struct forward_adapter_impl_zero<MD, F, FC,
+ typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
{
inline typename boost::result_of< FC() >::type
operator()() const
@@ -158,6 +180,13 @@ namespace boost
{
return static_cast<MD*>(this)->target_function()();
}
+ };
+
+ template< class MD, class F, class FC >
+ struct forward_adapter_impl<MD,F,FC,0,0>
+ : forward_adapter_impl_zero<MD,F,FC>
+ {
+ using forward_adapter_impl_zero<MD,F,FC>::operator();
// closing brace gets generated by preprocessing code, below
diff --git a/boost/functional/hash/hash.hpp b/boost/functional/hash/hash.hpp
index 2fb9f21116..0a8ceeb474 100644
--- a/boost/functional/hash/hash.hpp
+++ b/boost/functional/hash/hash.hpp
@@ -212,7 +212,6 @@ namespace boost
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
- template <typename SizeT>
inline void hash_combine_impl(boost::uint32_t& h1,
boost::uint32_t k1)
{
@@ -229,12 +228,11 @@ namespace boost
}
-// Don't define 64-bit hash combine on platforms with 64 bit integers,
+// Don't define 64-bit hash combine on platforms without 64 bit integers,
// and also not for 32-bit gcc as it warns about the 64-bit constant.
#if !defined(BOOST_NO_INT64_T) && \
!(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
- template <typename SizeT>
inline void hash_combine_impl(boost::uint64_t& h,
boost::uint64_t k)
{
@@ -247,6 +245,10 @@ namespace boost
h ^= k;
h *= m;
+
+ // Completely arbitrary number, to prevent 0's
+ // from hashing to 0.
+ h += 0xe6546b64;
}
#endif // BOOST_NO_INT64_T
diff --git a/boost/functional/lightweight_forward_adapter.hpp b/boost/functional/lightweight_forward_adapter.hpp
index 637aa9e19c..2706d299dd 100644
--- a/boost/functional/lightweight_forward_adapter.hpp
+++ b/boost/functional/lightweight_forward_adapter.hpp
@@ -149,8 +149,31 @@ namespace boost
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
- template< class MD, class F, class FC >
- struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
+ // When operator() doesn't have any parameters, it can't
+ // be templatized and can't use SFINAE, so intead use class
+ // template parameter SFINAE to decide whether to instantiate it.
+
+ template <typename T, typename R = void>
+ struct lightweight_forward_adapter_sfinae
+ {
+ typedef T type;
+ };
+
+ // This is the fallback for when there isn't an operator()(),
+ // need to create an operator() that will never instantiate
+ // so that using parent::operator() will work okay.
+ template< class MD, class F, class FC, class Enable = void>
+ struct lightweight_forward_adapter_impl_zero
+ : lightweight_forward_adapter_result
+ {
+ template <typename T> struct never_instantiate {};
+ template <typename T>
+ typename never_instantiate<T>::type operator()(T) const {}
+ };
+
+ template< class MD, class F, class FC>
+ struct lightweight_forward_adapter_impl_zero<MD, F, FC,
+ typename lightweight_forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
: lightweight_forward_adapter_result
{
inline typename boost::result_of< FC() >::type
@@ -166,6 +189,12 @@ namespace boost
}
};
+ template< class MD, class F, class FC >
+ struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
+ : lightweight_forward_adapter_impl_zero<MD,F,FC>
+ {
+ };
+
# define BOOST_PP_FILENAME_1 \
<boost/functional/lightweight_forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS \