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