Files
container_hash/doc/portability.qbk
T
Daniel James 27e69dea72 Merge hash and unordered changes.
Remove deprecated headers, move hash_fwd.hpp into hash subdirectory. And
several minor internal changes.
Mostly minor internal details.

Merged revisions 51262-51263,51407-51409,51504-51505,51644-51646,51667 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r51262 | danieljames | 2009-02-15 19:32:04 +0000 (Sun, 15 Feb 2009) | 1 line
  
  Use the new 'boost:' links for the hash, unordered and quickbook documentation.
........
  r51263 | danieljames | 2009-02-15 19:32:19 +0000 (Sun, 15 Feb 2009) | 2 lines
  
  Don't copy images for the standalone hash and unordered documentation, was only
  really required before the libraries were integrated into boost.
........
  r51407 | danieljames | 2009-02-22 23:49:51 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Fix the hash dirname.
........
  r51408 | danieljames | 2009-02-22 23:50:04 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Make copy_buckets and move_buckets member functions - so that calling them is a bit simpler.
........
  r51409 | danieljames | 2009-02-22 23:50:20 +0000 (Sun, 22 Feb 2009) | 1 line
  
  Move some of the data structure classes out of hash table data.
........
  r51504 | danieljames | 2009-03-01 14:15:09 +0000 (Sun, 01 Mar 2009) | 1 line
  
  Add missing return for operator=.
........
  r51505 | danieljames | 2009-03-01 14:15:39 +0000 (Sun, 01 Mar 2009) | 3 lines
  
  Make the sort stable.
  
  Doesn't really matter, but it might as well be.
........
  r51644 | danieljames | 2009-03-08 09:44:51 +0000 (Sun, 08 Mar 2009) | 1 line
  
  Detab.
........
  r51645 | danieljames | 2009-03-08 09:45:11 +0000 (Sun, 08 Mar 2009) | 4 lines
  
  Move hash_fwd into the hash subdirectory.
  
  I should have done this in the last release. But now all of the hash
  implementation is in the hash subdirectory.
........
  r51646 | danieljames | 2009-03-08 09:45:30 +0000 (Sun, 08 Mar 2009) | 3 lines
  
  Remove deprecated headers.
  
  Fixes #2412.
........
  r51667 | danieljames | 2009-03-09 20:56:23 +0000 (Mon, 09 Mar 2009) | 1 line
  
  Update copyright dates in hash and unordered.
........


[SVN r51729]
2009-03-11 22:51:09 +00:00

106 lines
3.2 KiB
Plaintext

[/ Copyright 2005-2008 Daniel James.
/ 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) ]
[section:portability Portability]
[def __boost_hash__ [classref boost::hash]]
__boost_hash__ is written to be as portable as possible, but unfortunately, several
older compilers don't support argument dependent lookup (ADL) - the mechanism
used for customisation. On those compilers custom overloads for `hash_value`
needs to be declared in the boost namespace.
On a strictly standards compliant compiler, an overload defined in the
boost namespace won't be found when __boost_hash__ is instantiated,
so for these compilers the overload should only be declared in the same
namespace as the class.
Let's say we have a simple custom type:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
friend std::size_t hash_value(custom_type x)
{
__boost_hash__<int> hasher;
return hasher(x.value);
}
};
}
On a compliant compiler, when `hash_value` is called for this type,
it will look at the namespace inside the type and find `hash_value`
but on a compiler which doesn't support ADL `hash_value` won't be found.
To make things worse, some compilers which do support ADL won't find
a friend class defined inside the class.
So first move the member function out of the class:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash(custom_type x)
{
__boost_hash__<T> hasher;
return hasher(value);
}
};
template <class T>
inline std::size_t hash_value(custom_type<T> x)
{
return x.hash();
}
}
Unfortunately, I couldn't declare hash_value as a friend, as some compilers
don't support template friends, so instead I declared a member function to
calculate the hash, and called it from hash_value.
For compilers which don't support ADL, hash_value needs to be defined in the
boost namespace:
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[h2 Other Issues]
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
When using GCC on Solaris, `boost::hash_value(long double)` treats
`long double`s as `double`s - so the hash function doesn't take into account the
full range of values.
[endsect]