diff options
Diffstat (limited to 'boost/functional')
-rw-r--r-- | boost/functional/forward_adapter.hpp | 33 | ||||
-rw-r--r-- | boost/functional/hash/hash.hpp | 8 | ||||
-rw-r--r-- | boost/functional/lightweight_forward_adapter.hpp | 33 |
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 \ |