epoc32/include/stdapis/boost/functional/hash/hash.hpp
branchSymbian2
changeset 2 2fe1408b6811
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/stdapis/boost/functional/hash/hash.hpp	Tue Mar 16 16:12:26 2010 +0000
     1.3 @@ -0,0 +1,595 @@
     1.4 +
     1.5 +//  Copyright Daniel James 2005-2006. Use, modification, and distribution are
     1.6 +//  subject to the Boost Software License, Version 1.0. (See accompanying
     1.7 +//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     1.8 +
     1.9 +//  Based on Peter Dimov's proposal
    1.10 +//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
    1.11 +//  issue 6.18. 
    1.12 +/*
    1.13 + * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
    1.14 +*/
    1.15 +#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
    1.16 +#define BOOST_FUNCTIONAL_HASH_HASH_HPP
    1.17 +
    1.18 +#include <boost/functional/hash_fwd.hpp>
    1.19 +#include <functional>
    1.20 +#include <boost/functional/detail/hash_float.hpp>
    1.21 +#include <boost/functional/detail/container_fwd.hpp>
    1.22 +#include <string>
    1.23 +
    1.24 +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    1.25 +#include <boost/type_traits/is_pointer.hpp>
    1.26 +#endif
    1.27 +
    1.28 +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
    1.29 +#include <boost/type_traits/is_array.hpp>
    1.30 +#endif
    1.31 +
    1.32 +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    1.33 +#include <boost/type_traits/is_const.hpp>
    1.34 +#endif
    1.35 +
    1.36 +namespace boost
    1.37 +{
    1.38 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
    1.39 +    // Borland complains about an ambiguous function overload
    1.40 +    // when compiling boost::hash<bool>.
    1.41 +    std::size_t hash_value(bool);
    1.42 +#endif
    1.43 +    
    1.44 +    std::size_t hash_value(int);
    1.45 +    std::size_t hash_value(unsigned int);
    1.46 +    std::size_t hash_value(long);
    1.47 +    std::size_t hash_value(unsigned long);
    1.48 +
    1.49 +#if defined(BOOST_MSVC) && defined(_WIN64)
    1.50 +    // On 64-bit windows std::size_t is a typedef for unsigned long long, which
    1.51 +    // isn't due to be supported until Boost 1.35. So add support here.
    1.52 +    // (Technically, Boost.Hash isn't actually documented as supporting
    1.53 +    // std::size_t. But it would be pretty silly not to).
    1.54 +    std::size_t hash_value(std::size_t);
    1.55 +#endif
    1.56 +
    1.57 +#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
    1.58 +    template <class T> std::size_t hash_value(T* const&);
    1.59 +#else
    1.60 +    template <class T> std::size_t hash_value(T*);
    1.61 +#endif
    1.62 +
    1.63 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
    1.64 +    template< class T, unsigned N >
    1.65 +    std::size_t hash_value(const T (&array)[N]);
    1.66 +
    1.67 +    template< class T, unsigned N >
    1.68 +    std::size_t hash_value(T (&array)[N]);
    1.69 +#endif
    1.70 +
    1.71 +    std::size_t hash_value(float v);
    1.72 +    std::size_t hash_value(double v);
    1.73 +    std::size_t hash_value(long double v);
    1.74 +
    1.75 +    template <class Ch, class A>
    1.76 +    std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
    1.77 +
    1.78 +    template <class A, class B>
    1.79 +    std::size_t hash_value(std::pair<A, B> const&);
    1.80 +    template <class T, class A>
    1.81 +    std::size_t hash_value(std::vector<T, A> const&);
    1.82 +    template <class T, class A>
    1.83 +    std::size_t hash_value(std::list<T, A> const& v);
    1.84 +    template <class T, class A>
    1.85 +    std::size_t hash_value(std::deque<T, A> const& v);
    1.86 +    template <class K, class C, class A>
    1.87 +    std::size_t hash_value(std::set<K, C, A> const& v);
    1.88 +    template <class K, class C, class A>
    1.89 +    std::size_t hash_value(std::multiset<K, C, A> const& v);
    1.90 +    template <class K, class T, class C, class A>
    1.91 +    std::size_t hash_value(std::map<K, T, C, A> const& v);
    1.92 +    template <class K, class T, class C, class A>
    1.93 +    std::size_t hash_value(std::multimap<K, T, C, A> const& v);
    1.94 +
    1.95 +    // Implementation
    1.96 +
    1.97 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
    1.98 +    inline std::size_t hash_value(bool v)
    1.99 +    {
   1.100 +        return static_cast<std::size_t>(v);
   1.101 +    }
   1.102 +#endif
   1.103 +
   1.104 +    inline std::size_t hash_value(int v)
   1.105 +    {
   1.106 +        return static_cast<std::size_t>(v);
   1.107 +    }
   1.108 +
   1.109 +    inline std::size_t hash_value(unsigned int v)
   1.110 +    {
   1.111 +        return static_cast<std::size_t>(v);
   1.112 +    }
   1.113 +
   1.114 +    inline std::size_t hash_value(long v)
   1.115 +    {
   1.116 +        return static_cast<std::size_t>(v);
   1.117 +    }
   1.118 +
   1.119 +    inline std::size_t hash_value(unsigned long v)
   1.120 +    {
   1.121 +        return static_cast<std::size_t>(v);
   1.122 +    }
   1.123 +
   1.124 +#if defined(_M_X64) && defined(_WIN64)
   1.125 +    inline std::size_t hash_value(long long v)
   1.126 +    {
   1.127 +        return v;
   1.128 +    }
   1.129 +
   1.130 +    inline std::size_t hash_value(unsigned long long v)
   1.131 +    {
   1.132 +        return v;
   1.133 +    }
   1.134 +#endif
   1.135 +
   1.136 +    // Implementation by Alberto Barbati and Dave Harris.
   1.137 +#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
   1.138 +    template <class T> std::size_t hash_value(T* const& v)
   1.139 +#else
   1.140 +    template <class T> std::size_t hash_value(T* v)
   1.141 +#endif
   1.142 +    {
   1.143 +        std::size_t x = static_cast<std::size_t>(
   1.144 +           reinterpret_cast<std::ptrdiff_t>(v));
   1.145 +        return x + (x >> 3);
   1.146 +    }
   1.147 +
   1.148 +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   1.149 +    template <class T>
   1.150 +    inline void hash_combine(std::size_t& seed, T& v)
   1.151 +#else
   1.152 +    template <class T>
   1.153 +    inline void hash_combine(std::size_t& seed, T const& v)
   1.154 +#endif
   1.155 +    {
   1.156 +        boost::hash<T> hasher;
   1.157 +        seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
   1.158 +    }
   1.159 +
   1.160 +    template <class It>
   1.161 +    inline std::size_t hash_range(It first, It last)
   1.162 +    {
   1.163 +        std::size_t seed = 0;
   1.164 +
   1.165 +        for(; first != last; ++first)
   1.166 +        {
   1.167 +            hash_combine(seed, *first);
   1.168 +        }
   1.169 +
   1.170 +        return seed;
   1.171 +    }
   1.172 +
   1.173 +    template <class It>
   1.174 +    inline void hash_range(std::size_t& seed, It first, It last)
   1.175 +    {
   1.176 +        for(; first != last; ++first)
   1.177 +        {
   1.178 +            hash_combine(seed, *first);
   1.179 +        }
   1.180 +    }
   1.181 +
   1.182 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
   1.183 +    template <class T>
   1.184 +    inline std::size_t hash_range(T* first, T* last)
   1.185 +    {
   1.186 +        std::size_t seed = 0;
   1.187 +
   1.188 +        for(; first != last; ++first)
   1.189 +        {
   1.190 +            boost::hash<T> hasher;
   1.191 +            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
   1.192 +        }
   1.193 +
   1.194 +        return seed;
   1.195 +    }
   1.196 +
   1.197 +    template <class T>
   1.198 +    inline void hash_range(std::size_t& seed, T* first, T* last)
   1.199 +    {
   1.200 +        for(; first != last; ++first)
   1.201 +        {
   1.202 +            boost::hash<T> hasher;
   1.203 +            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
   1.204 +        }
   1.205 +    }
   1.206 +#endif
   1.207 +
   1.208 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
   1.209 +    template< class T, unsigned N >
   1.210 +    inline std::size_t hash_value(const T (&array)[N])
   1.211 +    {
   1.212 +        return hash_range(array, array + N);
   1.213 +    }
   1.214 +
   1.215 +    template< class T, unsigned N >
   1.216 +    inline std::size_t hash_value(T (&array)[N])
   1.217 +    {
   1.218 +        return hash_range(array, array + N);
   1.219 +    }
   1.220 +#endif
   1.221 +
   1.222 +    template <class Ch, class A>
   1.223 +    inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
   1.224 +    {
   1.225 +        return hash_range(v.begin(), v.end());
   1.226 +    }
   1.227 +
   1.228 +    inline std::size_t hash_value(float v)
   1.229 +    {
   1.230 +        return boost::hash_detail::float_hash_value(v);
   1.231 +    }
   1.232 +
   1.233 +    inline std::size_t hash_value(double v)
   1.234 +    {
   1.235 +        return boost::hash_detail::float_hash_value(v);
   1.236 +    }
   1.237 +
   1.238 +#ifndef __SYMBIAN32__ //long double not supported
   1.239 +    inline std::size_t hash_value(long double v)
   1.240 +    {
   1.241 +        return boost::hash_detail::float_hash_value(v);
   1.242 +    }
   1.243 +#endif
   1.244 +    template <class A, class B>
   1.245 +    std::size_t hash_value(std::pair<A, B> const& v)
   1.246 +    {
   1.247 +        std::size_t seed = 0;
   1.248 +        hash_combine(seed, v.first);
   1.249 +        hash_combine(seed, v.second);
   1.250 +        return seed;
   1.251 +    }
   1.252 +
   1.253 +    template <class T, class A>
   1.254 +    std::size_t hash_value(std::vector<T, A> const& v)
   1.255 +    {
   1.256 +        return hash_range(v.begin(), v.end());
   1.257 +    }
   1.258 +
   1.259 +    template <class T, class A>
   1.260 +    std::size_t hash_value(std::list<T, A> const& v)
   1.261 +    {
   1.262 +        return hash_range(v.begin(), v.end());
   1.263 +    }
   1.264 +
   1.265 +    template <class T, class A>
   1.266 +    std::size_t hash_value(std::deque<T, A> const& v)
   1.267 +    {
   1.268 +        return hash_range(v.begin(), v.end());
   1.269 +    }
   1.270 +
   1.271 +    template <class K, class C, class A>
   1.272 +    std::size_t hash_value(std::set<K, C, A> const& v)
   1.273 +    {
   1.274 +        return hash_range(v.begin(), v.end());
   1.275 +    }
   1.276 +
   1.277 +    template <class K, class C, class A>
   1.278 +    std::size_t hash_value(std::multiset<K, C, A> const& v)
   1.279 +    {
   1.280 +        return hash_range(v.begin(), v.end());
   1.281 +    }
   1.282 +
   1.283 +    template <class K, class T, class C, class A>
   1.284 +    std::size_t hash_value(std::map<K, T, C, A> const& v)
   1.285 +    {
   1.286 +        return hash_range(v.begin(), v.end());
   1.287 +    }
   1.288 +
   1.289 +    template <class K, class T, class C, class A>
   1.290 +    std::size_t hash_value(std::multimap<K, T, C, A> const& v)
   1.291 +    {
   1.292 +        return hash_range(v.begin(), v.end());
   1.293 +    }
   1.294 +
   1.295 +    //
   1.296 +    // boost::hash
   1.297 +    //
   1.298 +
   1.299 +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   1.300 +#define BOOST_HASH_SPECIALIZE(type) \
   1.301 +    template <> struct hash<type> \
   1.302 +         : public std::unary_function<type, std::size_t> \
   1.303 +    { \
   1.304 +        std::size_t operator()(type v) const \
   1.305 +        { \
   1.306 +            return boost::hash_value(v); \
   1.307 +        } \
   1.308 +    };
   1.309 +
   1.310 +#define BOOST_HASH_SPECIALIZE_REF(type) \
   1.311 +    template <> struct hash<type> \
   1.312 +         : public std::unary_function<type, std::size_t> \
   1.313 +    { \
   1.314 +        std::size_t operator()(type const& v) const \
   1.315 +        { \
   1.316 +            return boost::hash_value(v); \
   1.317 +        } \
   1.318 +    };
   1.319 +#else
   1.320 +#define BOOST_HASH_SPECIALIZE(type) \
   1.321 +    template <> struct hash<type> \
   1.322 +         : public std::unary_function<type, std::size_t> \
   1.323 +    { \
   1.324 +        std::size_t operator()(type v) const \
   1.325 +        { \
   1.326 +            return boost::hash_value(v); \
   1.327 +        } \
   1.328 +    }; \
   1.329 +    \
   1.330 +    template <> struct hash<const type> \
   1.331 +         : public std::unary_function<const type, std::size_t> \
   1.332 +    { \
   1.333 +        std::size_t operator()(const type v) const \
   1.334 +        { \
   1.335 +            return boost::hash_value(v); \
   1.336 +        } \
   1.337 +    };
   1.338 +
   1.339 +#define BOOST_HASH_SPECIALIZE_REF(type) \
   1.340 +    template <> struct hash<type> \
   1.341 +         : public std::unary_function<type, std::size_t> \
   1.342 +    { \
   1.343 +        std::size_t operator()(type const& v) const \
   1.344 +        { \
   1.345 +            return boost::hash_value(v); \
   1.346 +        } \
   1.347 +    }; \
   1.348 +    \
   1.349 +    template <> struct hash<const type> \
   1.350 +         : public std::unary_function<const type, std::size_t> \
   1.351 +    { \
   1.352 +        std::size_t operator()(type const& v) const \
   1.353 +        { \
   1.354 +            return boost::hash_value(v); \
   1.355 +        } \
   1.356 +    };
   1.357 +#endif
   1.358 +
   1.359 +    BOOST_HASH_SPECIALIZE(bool)
   1.360 +    BOOST_HASH_SPECIALIZE(char)
   1.361 +    BOOST_HASH_SPECIALIZE(signed char)
   1.362 +    BOOST_HASH_SPECIALIZE(unsigned char)
   1.363 +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) || defined(__SYMBIAN32__)
   1.364 +    BOOST_HASH_SPECIALIZE(wchar_t)
   1.365 +#endif
   1.366 +    BOOST_HASH_SPECIALIZE(short)
   1.367 +    BOOST_HASH_SPECIALIZE(unsigned short)
   1.368 +    BOOST_HASH_SPECIALIZE(int)
   1.369 +    BOOST_HASH_SPECIALIZE(unsigned int)
   1.370 +    BOOST_HASH_SPECIALIZE(long)
   1.371 +    BOOST_HASH_SPECIALIZE(unsigned long)
   1.372 +
   1.373 +    BOOST_HASH_SPECIALIZE(float)
   1.374 +    BOOST_HASH_SPECIALIZE(double)
   1.375 +    BOOST_HASH_SPECIALIZE(long double)
   1.376 +
   1.377 +    BOOST_HASH_SPECIALIZE_REF(std::string)
   1.378 +#if !defined(BOOST_NO_STD_WSTRING)
   1.379 +    BOOST_HASH_SPECIALIZE_REF(std::wstring)
   1.380 +#endif
   1.381 +
   1.382 +#undef BOOST_HASH_SPECIALIZE
   1.383 +#undef BOOST_HASH_SPECIALIZE_REF
   1.384 +
   1.385 +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
   1.386 +    template <class T>
   1.387 +    struct hash<T*>
   1.388 +        : public std::unary_function<T*, std::size_t>
   1.389 +    {
   1.390 +        std::size_t operator()(T* v) const \
   1.391 +        { \
   1.392 +            return boost::hash_value(v); \
   1.393 +        } \
   1.394 +    };
   1.395 +#else
   1.396 +    namespace hash_detail
   1.397 +    {
   1.398 +        template <bool IsPointer>
   1.399 +        struct hash_impl;
   1.400 +
   1.401 +        template <>
   1.402 +        struct hash_impl<true>
   1.403 +        {
   1.404 +            template <class T>
   1.405 +            struct inner
   1.406 +                : public std::unary_function<T, std::size_t>
   1.407 +            {
   1.408 +                std::size_t operator()(T val) const
   1.409 +                {
   1.410 +                    return boost::hash_value(val);
   1.411 +                }
   1.412 +            };
   1.413 +        };
   1.414 +    }
   1.415 +
   1.416 +    template <class T> struct hash
   1.417 +        : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
   1.418 +            ::BOOST_NESTED_TEMPLATE inner<T>
   1.419 +    {
   1.420 +    };
   1.421 +#endif
   1.422 +}
   1.423 +
   1.424 +#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
   1.425 +
   1.426 +////////////////////////////////////////////////////////////////////////////////
   1.427 +
   1.428 +#if !defined(BOOST_HASH_NO_EXTENSIONS) \
   1.429 +    && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
   1.430 +#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
   1.431 +
   1.432 +namespace boost
   1.433 +{
   1.434 +
   1.435 +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
   1.436 +    namespace hash_detail
   1.437 +    {
   1.438 +        template <bool IsArray>
   1.439 +        struct call_hash_impl
   1.440 +        {
   1.441 +            template <class T>
   1.442 +            struct inner
   1.443 +            {
   1.444 +                static std::size_t call(T const& v)
   1.445 +                {
   1.446 +                    using namespace boost;
   1.447 +                    return hash_value(v);
   1.448 +                }
   1.449 +            };
   1.450 +        };
   1.451 +
   1.452 +        template <>
   1.453 +        struct call_hash_impl<true>
   1.454 +        {
   1.455 +            template <class Array>
   1.456 +            struct inner
   1.457 +            {
   1.458 +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   1.459 +                static std::size_t call(Array const& v)
   1.460 +#else
   1.461 +                static std::size_t call(Array& v)
   1.462 +#endif
   1.463 +                {
   1.464 +                    const int size = sizeof(v) / sizeof(*v);
   1.465 +                    return boost::hash_range(v, v + size);
   1.466 +                }
   1.467 +            };
   1.468 +        };
   1.469 +
   1.470 +        template <class T>
   1.471 +        struct call_hash
   1.472 +            : public call_hash_impl<boost::is_array<T>::value>
   1.473 +                ::BOOST_NESTED_TEMPLATE inner<T>
   1.474 +        {
   1.475 +        };
   1.476 +    }
   1.477 +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
   1.478 +
   1.479 +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
   1.480 +
   1.481 +    template <class T> struct hash
   1.482 +        : std::unary_function<T, std::size_t>
   1.483 +    {
   1.484 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
   1.485 +        std::size_t operator()(T const& val) const
   1.486 +        {
   1.487 +            return hash_value(val);
   1.488 +        }
   1.489 +#else
   1.490 +        std::size_t operator()(T const& val) const
   1.491 +        {
   1.492 +            return hash_detail::call_hash<T>::call(val);
   1.493 +        }
   1.494 +#endif
   1.495 +    };
   1.496 +
   1.497 +#if BOOST_WORKAROUND(__DMC__, <= 0x848)
   1.498 +    template <class T, unsigned int n> struct hash<T[n]>
   1.499 +        : std::unary_function<T[n], std::size_t>
   1.500 +    {
   1.501 +        std::size_t operator()(const T* val) const
   1.502 +        {
   1.503 +            return boost::hash_range(val, val+n);
   1.504 +        }
   1.505 +    };
   1.506 +#endif
   1.507 +
   1.508 +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.509 +
   1.510 +    // On compilers without partial specialization, boost::hash<T>
   1.511 +    // has already been declared to deal with pointers, so just
   1.512 +    // need to supply the non-pointer version.
   1.513 +
   1.514 +    namespace hash_detail
   1.515 +    {
   1.516 +        template <bool IsPointer>
   1.517 +        struct hash_impl;
   1.518 +
   1.519 +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   1.520 +
   1.521 +        template <>
   1.522 +        struct hash_impl<false>
   1.523 +        {
   1.524 +            template <class T>
   1.525 +            struct inner
   1.526 +                : std::unary_function<T, std::size_t>
   1.527 +            {
   1.528 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
   1.529 +                std::size_t operator()(T const& val) const
   1.530 +                {
   1.531 +                    return hash_value(val);
   1.532 +                }
   1.533 +#else
   1.534 +                std::size_t operator()(T const& val) const
   1.535 +                {
   1.536 +                    return hash_detail::call_hash<T>::call(val);
   1.537 +                }
   1.538 +#endif
   1.539 +            };
   1.540 +        };
   1.541 +
   1.542 +#else // Visual C++ 6.5
   1.543 +
   1.544 +    // There's probably a more elegant way to Visual C++ 6.5 to work
   1.545 +    // but I don't know what it is.
   1.546 +
   1.547 +        template <bool IsConst>
   1.548 +        struct hash_impl_msvc
   1.549 +        {
   1.550 +            template <class T>
   1.551 +            struct inner
   1.552 +                : public std::unary_function<T, std::size_t>
   1.553 +            {
   1.554 +                std::size_t operator()(T const& val) const
   1.555 +                {
   1.556 +                    return hash_detail::call_hash<T const>::call(val);
   1.557 +                }
   1.558 +
   1.559 +                std::size_t operator()(T& val) const
   1.560 +                {
   1.561 +                    return hash_detail::call_hash<T>::call(val);
   1.562 +                }
   1.563 +            };
   1.564 +        };
   1.565 +
   1.566 +        template <>
   1.567 +        struct hash_impl_msvc<true>
   1.568 +        {
   1.569 +            template <class T>
   1.570 +            struct inner
   1.571 +                : public std::unary_function<T, std::size_t>
   1.572 +            {
   1.573 +                std::size_t operator()(T& val) const
   1.574 +                {
   1.575 +                    return hash_detail::call_hash<T>::call(val);
   1.576 +                }
   1.577 +            };
   1.578 +        };
   1.579 +        
   1.580 +        template <class T>
   1.581 +        struct hash_impl_msvc2
   1.582 +            : public hash_impl_msvc<boost::is_const<T>::value>
   1.583 +                    ::BOOST_NESTED_TEMPLATE inner<T> {};
   1.584 +        
   1.585 +        template <>
   1.586 +        struct hash_impl<false>
   1.587 +        {
   1.588 +            template <class T>
   1.589 +            struct inner : public hash_impl_msvc2<T> {};
   1.590 +        };
   1.591 +
   1.592 +#endif // Visual C++ 6.5
   1.593 +    }
   1.594 +#endif  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.595 +}
   1.596 +
   1.597 +#endif
   1.598 +