os/ossrv/ossrv_pub/boost_apis/boost/functional/hash/hash.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
sl@0
     2
//  Copyright Daniel James 2005-2006. Use, modification, and distribution are
sl@0
     3
//  subject to the Boost Software License, Version 1.0. (See accompanying
sl@0
     4
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
     5
sl@0
     6
//  Based on Peter Dimov's proposal
sl@0
     7
//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
sl@0
     8
//  issue 6.18. 
sl@0
     9
/*
sl@0
    10
 * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
sl@0
    11
*/
sl@0
    12
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
sl@0
    13
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
sl@0
    14
sl@0
    15
#include <boost/functional/hash_fwd.hpp>
sl@0
    16
#include <functional>
sl@0
    17
#include <boost/functional/detail/hash_float.hpp>
sl@0
    18
#include <boost/functional/detail/container_fwd.hpp>
sl@0
    19
#include <string>
sl@0
    20
sl@0
    21
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
sl@0
    22
#include <boost/type_traits/is_pointer.hpp>
sl@0
    23
#endif
sl@0
    24
sl@0
    25
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
    26
#include <boost/type_traits/is_array.hpp>
sl@0
    27
#endif
sl@0
    28
sl@0
    29
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
sl@0
    30
#include <boost/type_traits/is_const.hpp>
sl@0
    31
#endif
sl@0
    32
sl@0
    33
namespace boost
sl@0
    34
{
sl@0
    35
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
sl@0
    36
    // Borland complains about an ambiguous function overload
sl@0
    37
    // when compiling boost::hash<bool>.
sl@0
    38
    std::size_t hash_value(bool);
sl@0
    39
#endif
sl@0
    40
    
sl@0
    41
    std::size_t hash_value(int);
sl@0
    42
    std::size_t hash_value(unsigned int);
sl@0
    43
    std::size_t hash_value(long);
sl@0
    44
    std::size_t hash_value(unsigned long);
sl@0
    45
sl@0
    46
#if defined(BOOST_MSVC) && defined(_WIN64)
sl@0
    47
    // On 64-bit windows std::size_t is a typedef for unsigned long long, which
sl@0
    48
    // isn't due to be supported until Boost 1.35. So add support here.
sl@0
    49
    // (Technically, Boost.Hash isn't actually documented as supporting
sl@0
    50
    // std::size_t. But it would be pretty silly not to).
sl@0
    51
    std::size_t hash_value(std::size_t);
sl@0
    52
#endif
sl@0
    53
sl@0
    54
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
sl@0
    55
    template <class T> std::size_t hash_value(T* const&);
sl@0
    56
#else
sl@0
    57
    template <class T> std::size_t hash_value(T*);
sl@0
    58
#endif
sl@0
    59
sl@0
    60
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
    61
    template< class T, unsigned N >
sl@0
    62
    std::size_t hash_value(const T (&array)[N]);
sl@0
    63
sl@0
    64
    template< class T, unsigned N >
sl@0
    65
    std::size_t hash_value(T (&array)[N]);
sl@0
    66
#endif
sl@0
    67
sl@0
    68
    std::size_t hash_value(float v);
sl@0
    69
    std::size_t hash_value(double v);
sl@0
    70
    std::size_t hash_value(long double v);
sl@0
    71
sl@0
    72
    template <class Ch, class A>
sl@0
    73
    std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
sl@0
    74
sl@0
    75
    template <class A, class B>
sl@0
    76
    std::size_t hash_value(std::pair<A, B> const&);
sl@0
    77
    template <class T, class A>
sl@0
    78
    std::size_t hash_value(std::vector<T, A> const&);
sl@0
    79
    template <class T, class A>
sl@0
    80
    std::size_t hash_value(std::list<T, A> const& v);
sl@0
    81
    template <class T, class A>
sl@0
    82
    std::size_t hash_value(std::deque<T, A> const& v);
sl@0
    83
    template <class K, class C, class A>
sl@0
    84
    std::size_t hash_value(std::set<K, C, A> const& v);
sl@0
    85
    template <class K, class C, class A>
sl@0
    86
    std::size_t hash_value(std::multiset<K, C, A> const& v);
sl@0
    87
    template <class K, class T, class C, class A>
sl@0
    88
    std::size_t hash_value(std::map<K, T, C, A> const& v);
sl@0
    89
    template <class K, class T, class C, class A>
sl@0
    90
    std::size_t hash_value(std::multimap<K, T, C, A> const& v);
sl@0
    91
sl@0
    92
    // Implementation
sl@0
    93
sl@0
    94
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
sl@0
    95
    inline std::size_t hash_value(bool v)
sl@0
    96
    {
sl@0
    97
        return static_cast<std::size_t>(v);
sl@0
    98
    }
sl@0
    99
#endif
sl@0
   100
sl@0
   101
    inline std::size_t hash_value(int v)
sl@0
   102
    {
sl@0
   103
        return static_cast<std::size_t>(v);
sl@0
   104
    }
sl@0
   105
sl@0
   106
    inline std::size_t hash_value(unsigned int v)
sl@0
   107
    {
sl@0
   108
        return static_cast<std::size_t>(v);
sl@0
   109
    }
sl@0
   110
sl@0
   111
    inline std::size_t hash_value(long v)
sl@0
   112
    {
sl@0
   113
        return static_cast<std::size_t>(v);
sl@0
   114
    }
sl@0
   115
sl@0
   116
    inline std::size_t hash_value(unsigned long v)
sl@0
   117
    {
sl@0
   118
        return static_cast<std::size_t>(v);
sl@0
   119
    }
sl@0
   120
sl@0
   121
#if defined(_M_X64) && defined(_WIN64)
sl@0
   122
    inline std::size_t hash_value(long long v)
sl@0
   123
    {
sl@0
   124
        return v;
sl@0
   125
    }
sl@0
   126
sl@0
   127
    inline std::size_t hash_value(unsigned long long v)
sl@0
   128
    {
sl@0
   129
        return v;
sl@0
   130
    }
sl@0
   131
#endif
sl@0
   132
sl@0
   133
    // Implementation by Alberto Barbati and Dave Harris.
sl@0
   134
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
sl@0
   135
    template <class T> std::size_t hash_value(T* const& v)
sl@0
   136
#else
sl@0
   137
    template <class T> std::size_t hash_value(T* v)
sl@0
   138
#endif
sl@0
   139
    {
sl@0
   140
        std::size_t x = static_cast<std::size_t>(
sl@0
   141
           reinterpret_cast<std::ptrdiff_t>(v));
sl@0
   142
        return x + (x >> 3);
sl@0
   143
    }
sl@0
   144
sl@0
   145
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
sl@0
   146
    template <class T>
sl@0
   147
    inline void hash_combine(std::size_t& seed, T& v)
sl@0
   148
#else
sl@0
   149
    template <class T>
sl@0
   150
    inline void hash_combine(std::size_t& seed, T const& v)
sl@0
   151
#endif
sl@0
   152
    {
sl@0
   153
        boost::hash<T> hasher;
sl@0
   154
        seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
sl@0
   155
    }
sl@0
   156
sl@0
   157
    template <class It>
sl@0
   158
    inline std::size_t hash_range(It first, It last)
sl@0
   159
    {
sl@0
   160
        std::size_t seed = 0;
sl@0
   161
sl@0
   162
        for(; first != last; ++first)
sl@0
   163
        {
sl@0
   164
            hash_combine(seed, *first);
sl@0
   165
        }
sl@0
   166
sl@0
   167
        return seed;
sl@0
   168
    }
sl@0
   169
sl@0
   170
    template <class It>
sl@0
   171
    inline void hash_range(std::size_t& seed, It first, It last)
sl@0
   172
    {
sl@0
   173
        for(; first != last; ++first)
sl@0
   174
        {
sl@0
   175
            hash_combine(seed, *first);
sl@0
   176
        }
sl@0
   177
    }
sl@0
   178
sl@0
   179
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
sl@0
   180
    template <class T>
sl@0
   181
    inline std::size_t hash_range(T* first, T* last)
sl@0
   182
    {
sl@0
   183
        std::size_t seed = 0;
sl@0
   184
sl@0
   185
        for(; first != last; ++first)
sl@0
   186
        {
sl@0
   187
            boost::hash<T> hasher;
sl@0
   188
            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
sl@0
   189
        }
sl@0
   190
sl@0
   191
        return seed;
sl@0
   192
    }
sl@0
   193
sl@0
   194
    template <class T>
sl@0
   195
    inline void hash_range(std::size_t& seed, T* first, T* last)
sl@0
   196
    {
sl@0
   197
        for(; first != last; ++first)
sl@0
   198
        {
sl@0
   199
            boost::hash<T> hasher;
sl@0
   200
            seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
sl@0
   201
        }
sl@0
   202
    }
sl@0
   203
#endif
sl@0
   204
sl@0
   205
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
   206
    template< class T, unsigned N >
sl@0
   207
    inline std::size_t hash_value(const T (&array)[N])
sl@0
   208
    {
sl@0
   209
        return hash_range(array, array + N);
sl@0
   210
    }
sl@0
   211
sl@0
   212
    template< class T, unsigned N >
sl@0
   213
    inline std::size_t hash_value(T (&array)[N])
sl@0
   214
    {
sl@0
   215
        return hash_range(array, array + N);
sl@0
   216
    }
sl@0
   217
#endif
sl@0
   218
sl@0
   219
    template <class Ch, class A>
sl@0
   220
    inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
sl@0
   221
    {
sl@0
   222
        return hash_range(v.begin(), v.end());
sl@0
   223
    }
sl@0
   224
sl@0
   225
    inline std::size_t hash_value(float v)
sl@0
   226
    {
sl@0
   227
        return boost::hash_detail::float_hash_value(v);
sl@0
   228
    }
sl@0
   229
sl@0
   230
    inline std::size_t hash_value(double v)
sl@0
   231
    {
sl@0
   232
        return boost::hash_detail::float_hash_value(v);
sl@0
   233
    }
sl@0
   234
sl@0
   235
#ifndef __SYMBIAN32__ //long double not supported
sl@0
   236
    inline std::size_t hash_value(long double v)
sl@0
   237
    {
sl@0
   238
        return boost::hash_detail::float_hash_value(v);
sl@0
   239
    }
sl@0
   240
#endif
sl@0
   241
    template <class A, class B>
sl@0
   242
    std::size_t hash_value(std::pair<A, B> const& v)
sl@0
   243
    {
sl@0
   244
        std::size_t seed = 0;
sl@0
   245
        hash_combine(seed, v.first);
sl@0
   246
        hash_combine(seed, v.second);
sl@0
   247
        return seed;
sl@0
   248
    }
sl@0
   249
sl@0
   250
    template <class T, class A>
sl@0
   251
    std::size_t hash_value(std::vector<T, A> const& v)
sl@0
   252
    {
sl@0
   253
        return hash_range(v.begin(), v.end());
sl@0
   254
    }
sl@0
   255
sl@0
   256
    template <class T, class A>
sl@0
   257
    std::size_t hash_value(std::list<T, A> const& v)
sl@0
   258
    {
sl@0
   259
        return hash_range(v.begin(), v.end());
sl@0
   260
    }
sl@0
   261
sl@0
   262
    template <class T, class A>
sl@0
   263
    std::size_t hash_value(std::deque<T, A> const& v)
sl@0
   264
    {
sl@0
   265
        return hash_range(v.begin(), v.end());
sl@0
   266
    }
sl@0
   267
sl@0
   268
    template <class K, class C, class A>
sl@0
   269
    std::size_t hash_value(std::set<K, C, A> const& v)
sl@0
   270
    {
sl@0
   271
        return hash_range(v.begin(), v.end());
sl@0
   272
    }
sl@0
   273
sl@0
   274
    template <class K, class C, class A>
sl@0
   275
    std::size_t hash_value(std::multiset<K, C, A> const& v)
sl@0
   276
    {
sl@0
   277
        return hash_range(v.begin(), v.end());
sl@0
   278
    }
sl@0
   279
sl@0
   280
    template <class K, class T, class C, class A>
sl@0
   281
    std::size_t hash_value(std::map<K, T, C, A> const& v)
sl@0
   282
    {
sl@0
   283
        return hash_range(v.begin(), v.end());
sl@0
   284
    }
sl@0
   285
sl@0
   286
    template <class K, class T, class C, class A>
sl@0
   287
    std::size_t hash_value(std::multimap<K, T, C, A> const& v)
sl@0
   288
    {
sl@0
   289
        return hash_range(v.begin(), v.end());
sl@0
   290
    }
sl@0
   291
sl@0
   292
    //
sl@0
   293
    // boost::hash
sl@0
   294
    //
sl@0
   295
sl@0
   296
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
sl@0
   297
#define BOOST_HASH_SPECIALIZE(type) \
sl@0
   298
    template <> struct hash<type> \
sl@0
   299
         : public std::unary_function<type, std::size_t> \
sl@0
   300
    { \
sl@0
   301
        std::size_t operator()(type v) const \
sl@0
   302
        { \
sl@0
   303
            return boost::hash_value(v); \
sl@0
   304
        } \
sl@0
   305
    };
sl@0
   306
sl@0
   307
#define BOOST_HASH_SPECIALIZE_REF(type) \
sl@0
   308
    template <> struct hash<type> \
sl@0
   309
         : public std::unary_function<type, std::size_t> \
sl@0
   310
    { \
sl@0
   311
        std::size_t operator()(type const& v) const \
sl@0
   312
        { \
sl@0
   313
            return boost::hash_value(v); \
sl@0
   314
        } \
sl@0
   315
    };
sl@0
   316
#else
sl@0
   317
#define BOOST_HASH_SPECIALIZE(type) \
sl@0
   318
    template <> struct hash<type> \
sl@0
   319
         : public std::unary_function<type, std::size_t> \
sl@0
   320
    { \
sl@0
   321
        std::size_t operator()(type v) const \
sl@0
   322
        { \
sl@0
   323
            return boost::hash_value(v); \
sl@0
   324
        } \
sl@0
   325
    }; \
sl@0
   326
    \
sl@0
   327
    template <> struct hash<const type> \
sl@0
   328
         : public std::unary_function<const type, std::size_t> \
sl@0
   329
    { \
sl@0
   330
        std::size_t operator()(const type v) const \
sl@0
   331
        { \
sl@0
   332
            return boost::hash_value(v); \
sl@0
   333
        } \
sl@0
   334
    };
sl@0
   335
sl@0
   336
#define BOOST_HASH_SPECIALIZE_REF(type) \
sl@0
   337
    template <> struct hash<type> \
sl@0
   338
         : public std::unary_function<type, std::size_t> \
sl@0
   339
    { \
sl@0
   340
        std::size_t operator()(type const& v) const \
sl@0
   341
        { \
sl@0
   342
            return boost::hash_value(v); \
sl@0
   343
        } \
sl@0
   344
    }; \
sl@0
   345
    \
sl@0
   346
    template <> struct hash<const type> \
sl@0
   347
         : public std::unary_function<const type, std::size_t> \
sl@0
   348
    { \
sl@0
   349
        std::size_t operator()(type const& v) const \
sl@0
   350
        { \
sl@0
   351
            return boost::hash_value(v); \
sl@0
   352
        } \
sl@0
   353
    };
sl@0
   354
#endif
sl@0
   355
sl@0
   356
    BOOST_HASH_SPECIALIZE(bool)
sl@0
   357
    BOOST_HASH_SPECIALIZE(char)
sl@0
   358
    BOOST_HASH_SPECIALIZE(signed char)
sl@0
   359
    BOOST_HASH_SPECIALIZE(unsigned char)
sl@0
   360
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) || defined(__SYMBIAN32__)
sl@0
   361
    BOOST_HASH_SPECIALIZE(wchar_t)
sl@0
   362
#endif
sl@0
   363
    BOOST_HASH_SPECIALIZE(short)
sl@0
   364
    BOOST_HASH_SPECIALIZE(unsigned short)
sl@0
   365
    BOOST_HASH_SPECIALIZE(int)
sl@0
   366
    BOOST_HASH_SPECIALIZE(unsigned int)
sl@0
   367
    BOOST_HASH_SPECIALIZE(long)
sl@0
   368
    BOOST_HASH_SPECIALIZE(unsigned long)
sl@0
   369
sl@0
   370
    BOOST_HASH_SPECIALIZE(float)
sl@0
   371
    BOOST_HASH_SPECIALIZE(double)
sl@0
   372
    BOOST_HASH_SPECIALIZE(long double)
sl@0
   373
sl@0
   374
    BOOST_HASH_SPECIALIZE_REF(std::string)
sl@0
   375
#if !defined(BOOST_NO_STD_WSTRING)
sl@0
   376
    BOOST_HASH_SPECIALIZE_REF(std::wstring)
sl@0
   377
#endif
sl@0
   378
sl@0
   379
#undef BOOST_HASH_SPECIALIZE
sl@0
   380
#undef BOOST_HASH_SPECIALIZE_REF
sl@0
   381
sl@0
   382
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
sl@0
   383
    template <class T>
sl@0
   384
    struct hash<T*>
sl@0
   385
        : public std::unary_function<T*, std::size_t>
sl@0
   386
    {
sl@0
   387
        std::size_t operator()(T* v) const \
sl@0
   388
        { \
sl@0
   389
            return boost::hash_value(v); \
sl@0
   390
        } \
sl@0
   391
    };
sl@0
   392
#else
sl@0
   393
    namespace hash_detail
sl@0
   394
    {
sl@0
   395
        template <bool IsPointer>
sl@0
   396
        struct hash_impl;
sl@0
   397
sl@0
   398
        template <>
sl@0
   399
        struct hash_impl<true>
sl@0
   400
        {
sl@0
   401
            template <class T>
sl@0
   402
            struct inner
sl@0
   403
                : public std::unary_function<T, std::size_t>
sl@0
   404
            {
sl@0
   405
                std::size_t operator()(T val) const
sl@0
   406
                {
sl@0
   407
                    return boost::hash_value(val);
sl@0
   408
                }
sl@0
   409
            };
sl@0
   410
        };
sl@0
   411
    }
sl@0
   412
sl@0
   413
    template <class T> struct hash
sl@0
   414
        : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
sl@0
   415
            ::BOOST_NESTED_TEMPLATE inner<T>
sl@0
   416
    {
sl@0
   417
    };
sl@0
   418
#endif
sl@0
   419
}
sl@0
   420
sl@0
   421
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
sl@0
   422
sl@0
   423
////////////////////////////////////////////////////////////////////////////////
sl@0
   424
sl@0
   425
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
sl@0
   426
    && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
sl@0
   427
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
sl@0
   428
sl@0
   429
namespace boost
sl@0
   430
{
sl@0
   431
sl@0
   432
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
   433
    namespace hash_detail
sl@0
   434
    {
sl@0
   435
        template <bool IsArray>
sl@0
   436
        struct call_hash_impl
sl@0
   437
        {
sl@0
   438
            template <class T>
sl@0
   439
            struct inner
sl@0
   440
            {
sl@0
   441
                static std::size_t call(T const& v)
sl@0
   442
                {
sl@0
   443
                    using namespace boost;
sl@0
   444
                    return hash_value(v);
sl@0
   445
                }
sl@0
   446
            };
sl@0
   447
        };
sl@0
   448
sl@0
   449
        template <>
sl@0
   450
        struct call_hash_impl<true>
sl@0
   451
        {
sl@0
   452
            template <class Array>
sl@0
   453
            struct inner
sl@0
   454
            {
sl@0
   455
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
sl@0
   456
                static std::size_t call(Array const& v)
sl@0
   457
#else
sl@0
   458
                static std::size_t call(Array& v)
sl@0
   459
#endif
sl@0
   460
                {
sl@0
   461
                    const int size = sizeof(v) / sizeof(*v);
sl@0
   462
                    return boost::hash_range(v, v + size);
sl@0
   463
                }
sl@0
   464
            };
sl@0
   465
        };
sl@0
   466
sl@0
   467
        template <class T>
sl@0
   468
        struct call_hash
sl@0
   469
            : public call_hash_impl<boost::is_array<T>::value>
sl@0
   470
                ::BOOST_NESTED_TEMPLATE inner<T>
sl@0
   471
        {
sl@0
   472
        };
sl@0
   473
    }
sl@0
   474
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
sl@0
   475
sl@0
   476
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
sl@0
   477
sl@0
   478
    template <class T> struct hash
sl@0
   479
        : std::unary_function<T, std::size_t>
sl@0
   480
    {
sl@0
   481
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
   482
        std::size_t operator()(T const& val) const
sl@0
   483
        {
sl@0
   484
            return hash_value(val);
sl@0
   485
        }
sl@0
   486
#else
sl@0
   487
        std::size_t operator()(T const& val) const
sl@0
   488
        {
sl@0
   489
            return hash_detail::call_hash<T>::call(val);
sl@0
   490
        }
sl@0
   491
#endif
sl@0
   492
    };
sl@0
   493
sl@0
   494
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
sl@0
   495
    template <class T, unsigned int n> struct hash<T[n]>
sl@0
   496
        : std::unary_function<T[n], std::size_t>
sl@0
   497
    {
sl@0
   498
        std::size_t operator()(const T* val) const
sl@0
   499
        {
sl@0
   500
            return boost::hash_range(val, val+n);
sl@0
   501
        }
sl@0
   502
    };
sl@0
   503
#endif
sl@0
   504
sl@0
   505
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
sl@0
   506
sl@0
   507
    // On compilers without partial specialization, boost::hash<T>
sl@0
   508
    // has already been declared to deal with pointers, so just
sl@0
   509
    // need to supply the non-pointer version.
sl@0
   510
sl@0
   511
    namespace hash_detail
sl@0
   512
    {
sl@0
   513
        template <bool IsPointer>
sl@0
   514
        struct hash_impl;
sl@0
   515
sl@0
   516
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
sl@0
   517
sl@0
   518
        template <>
sl@0
   519
        struct hash_impl<false>
sl@0
   520
        {
sl@0
   521
            template <class T>
sl@0
   522
            struct inner
sl@0
   523
                : std::unary_function<T, std::size_t>
sl@0
   524
            {
sl@0
   525
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
sl@0
   526
                std::size_t operator()(T const& val) const
sl@0
   527
                {
sl@0
   528
                    return hash_value(val);
sl@0
   529
                }
sl@0
   530
#else
sl@0
   531
                std::size_t operator()(T const& val) const
sl@0
   532
                {
sl@0
   533
                    return hash_detail::call_hash<T>::call(val);
sl@0
   534
                }
sl@0
   535
#endif
sl@0
   536
            };
sl@0
   537
        };
sl@0
   538
sl@0
   539
#else // Visual C++ 6.5
sl@0
   540
sl@0
   541
    // There's probably a more elegant way to Visual C++ 6.5 to work
sl@0
   542
    // but I don't know what it is.
sl@0
   543
sl@0
   544
        template <bool IsConst>
sl@0
   545
        struct hash_impl_msvc
sl@0
   546
        {
sl@0
   547
            template <class T>
sl@0
   548
            struct inner
sl@0
   549
                : public std::unary_function<T, std::size_t>
sl@0
   550
            {
sl@0
   551
                std::size_t operator()(T const& val) const
sl@0
   552
                {
sl@0
   553
                    return hash_detail::call_hash<T const>::call(val);
sl@0
   554
                }
sl@0
   555
sl@0
   556
                std::size_t operator()(T& val) const
sl@0
   557
                {
sl@0
   558
                    return hash_detail::call_hash<T>::call(val);
sl@0
   559
                }
sl@0
   560
            };
sl@0
   561
        };
sl@0
   562
sl@0
   563
        template <>
sl@0
   564
        struct hash_impl_msvc<true>
sl@0
   565
        {
sl@0
   566
            template <class T>
sl@0
   567
            struct inner
sl@0
   568
                : public std::unary_function<T, std::size_t>
sl@0
   569
            {
sl@0
   570
                std::size_t operator()(T& val) const
sl@0
   571
                {
sl@0
   572
                    return hash_detail::call_hash<T>::call(val);
sl@0
   573
                }
sl@0
   574
            };
sl@0
   575
        };
sl@0
   576
        
sl@0
   577
        template <class T>
sl@0
   578
        struct hash_impl_msvc2
sl@0
   579
            : public hash_impl_msvc<boost::is_const<T>::value>
sl@0
   580
                    ::BOOST_NESTED_TEMPLATE inner<T> {};
sl@0
   581
        
sl@0
   582
        template <>
sl@0
   583
        struct hash_impl<false>
sl@0
   584
        {
sl@0
   585
            template <class T>
sl@0
   586
            struct inner : public hash_impl_msvc2<T> {};
sl@0
   587
        };
sl@0
   588
sl@0
   589
#endif // Visual C++ 6.5
sl@0
   590
    }
sl@0
   591
#endif  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
sl@0
   592
}
sl@0
   593
sl@0
   594
#endif
sl@0
   595