OSDN Git Service

2006-09-19 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / functional
index abe92e3..ef85e5b 100644 (file)
@@ -1,6 +1,6 @@
 // TR1 functional header -*- C++ -*-
 
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -15,7 +15,7 @@
 
 // You should have received a copy of the GNU General Public License along
 // with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 // USA.
 
 // As a special exception, you may use this file as part of a free software
 #ifndef _TR1_FUNCTIONAL
 #define _TR1_FUNCTIONAL 1
 
+#pragma GCC system_header
+
 #include "../functional"
 #include <typeinfo>
 #include <tr1/type_traits>
-#include <bits/cpp_type_traits.h>
+#include <ext/type_traits.h>
 #include <string>               // for std::tr1::hash
 #include <cstdlib>              // for std::abort
+#include <cmath>                // for std::frexp
 #include <tr1/tuple>
 
 namespace std
 {
-namespace tr1
-{
+_GLIBCXX_BEGIN_NAMESPACE(tr1)
+
   template<typename _MemberPointer>
     class _Mem_fn;
 
@@ -103,7 +106,7 @@ namespace tr1
   */
   template<typename _Functor>
     struct _Weak_result_type_impl
-      : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
+    : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
     {
     };
 
@@ -211,33 +214,33 @@ namespace tr1
   // Not a unary_function or binary_function, so try a weak result type
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<false, false, _Tp>
-      : _Weak_result_type<_Tp>
+    : _Weak_result_type<_Tp>
     { };
 
   // unary_function but not binary_function
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<true, false, _Tp>
-      : unary_function<typename _Tp::argument_type,
-                       typename _Tp::result_type>
+    : unary_function<typename _Tp::argument_type,
+                    typename _Tp::result_type>
     { };
 
   // binary_function but not unary_function
   template<typename _Tp>
     struct _Reference_wrapper_base_impl<false, true, _Tp>
-      : binary_function<typename _Tp::first_argument_type,
-                        typename _Tp::second_argument_type,
-                        typename _Tp::result_type>
+    : binary_function<typename _Tp::first_argument_type,
+                     typename _Tp::second_argument_type,
+                     typename _Tp::result_type>
     { };
 
   // both unary_function and binary_function. import result_type to
   // avoid conflicts.
    template<typename _Tp>
     struct _Reference_wrapper_base_impl<true, true, _Tp>
-      : unary_function<typename _Tp::argument_type,
-                       typename _Tp::result_type>,
-        binary_function<typename _Tp::first_argument_type,
-                        typename _Tp::second_argument_type,
-                        typename _Tp::result_type>
+    : unary_function<typename _Tp::argument_type,
+                    typename _Tp::result_type>,
+      binary_function<typename _Tp::first_argument_type,
+                     typename _Tp::second_argument_type,
+                     typename _Tp::result_type>
     {
       typedef typename _Tp::result_type result_type;
     };
@@ -252,82 +255,82 @@ namespace tr1
   */
   template<typename _Tp>
     struct _Reference_wrapper_base
-      : _Reference_wrapper_base_impl<
-          _Derives_from_unary_function<_Tp>::value,
-          _Derives_from_binary_function<_Tp>::value,
-          _Tp>
+    : _Reference_wrapper_base_impl<
+      _Derives_from_unary_function<_Tp>::value,
+      _Derives_from_binary_function<_Tp>::value,
+      _Tp>
     { };
 
   // - a function type (unary)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res(_T1)>
-      : unary_function<_T1, _Res>
+    : unary_function<_T1, _Res>
     { };
 
   // - a function type (binary)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res(_T1, _T2)>
-      : binary_function<_T1, _T2, _Res>
+    : binary_function<_T1, _T2, _Res>
     { };
 
   // - a function pointer type (unary)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res(*)(_T1)>
-      : unary_function<_T1, _Res>
+    : unary_function<_T1, _Res>
     { };
 
   // - a function pointer type (binary)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
-      : binary_function<_T1, _T2, _Res>
+    : binary_function<_T1, _T2, _Res>
     { };
 
   // - a pointer to member function type (unary, no qualifiers)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res (_T1::*)()>
-      : unary_function<_T1*, _Res>
+    : unary_function<_T1*, _Res>
     { };
 
   // - a pointer to member function type (binary, no qualifiers)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
-      : binary_function<_T1*, _T2, _Res>
+    : binary_function<_T1*, _T2, _Res>
     { };
 
   // - a pointer to member function type (unary, const)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res (_T1::*)() const>
-      : unary_function<const _T1*, _Res>
+    : unary_function<const _T1*, _Res>
     { };
 
   // - a pointer to member function type (binary, const)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
-      : binary_function<const _T1*, _T2, _Res>
+    : binary_function<const _T1*, _T2, _Res>
     { };
 
   // - a pointer to member function type (unary, volatile)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
-      : unary_function<volatile _T1*, _Res>
+    : unary_function<volatile _T1*, _Res>
     { };
 
   // - a pointer to member function type (binary, volatile)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
-      : binary_function<volatile _T1*, _T2, _Res>
+    : binary_function<volatile _T1*, _T2, _Res>
     { };
 
   // - a pointer to member function type (unary, const volatile)
   template<typename _Res, typename _T1>
     struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
-      : unary_function<const volatile _T1*, _Res>
+    : unary_function<const volatile _T1*, _Res>
     { };
 
   // - a pointer to member function type (binary, const volatile)
   template<typename _Res, typename _T1, typename _T2>
     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
-      : binary_function<const volatile _T1*, _T2, _Res>
+    : binary_function<const volatile _T1*, _T2, _Res>
     { };
 
   template<typename _Tp>
@@ -371,22 +374,24 @@ namespace tr1
 
   // Denotes a reference should be taken to a variable.
   template<typename _Tp>
-    reference_wrapper<_Tp>
+    inline reference_wrapper<_Tp>
     ref(_Tp& __t)
     { return reference_wrapper<_Tp>(__t); }
 
   // Denotes a const reference should be taken to a variable.
   template<typename _Tp>
-    reference_wrapper<const _Tp>
+    inline reference_wrapper<const _Tp>
     cref(const _Tp& __t)
     { return reference_wrapper<const _Tp>(__t); }
 
   template<typename _Tp>
-    reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t)
+    inline reference_wrapper<_Tp>
+    ref(reference_wrapper<_Tp> __t)
     { return ref(__t.get()); }
 
   template<typename _Tp>
-    reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t)
+    inline reference_wrapper<const _Tp>
+    cref(reference_wrapper<_Tp> __t)
     { return cref(__t.get()); }
 
    template<typename _Tp, bool>
@@ -447,10 +452,10 @@ namespace tr1
   public:
     template<typename _Tp>
       struct _Result_type
-        : _Mem_fn_const_or_non<
-            _Res,
-            (sizeof(__sfinae_types::__two)
-             == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
+      : _Mem_fn_const_or_non<
+        _Res,
+        (sizeof(__sfinae_types::__two)
+        == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
       { };
 
     template<typename _Signature>
@@ -458,11 +463,11 @@ namespace tr1
 
     template<typename _CVMem, typename _Tp>
       struct result<_CVMem(_Tp)>
-        : public _Result_type<_Tp> { };
+      : public _Result_type<_Tp> { };
 
     template<typename _CVMem, typename _Tp>
       struct result<_CVMem(_Tp&)>
-        : public _Result_type<_Tp> { };
+      : public _Result_type<_Tp> { };
 
     explicit _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }
 
@@ -1090,75 +1095,189 @@ namespace tr1
 #undef _GLIBCXX_JOIN2
 #undef _GLIBCXX_JOIN
 
-// Definition of default hash function std::tr1::hash<>.  The types for
-// which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR.
-
-  template <typename T> struct hash;
-
-  #define tr1_hashtable_define_trivial_hash(T)                              \
-    template <> struct hash<T> {                                                    \
-      std::size_t operator()(T val) const { return static_cast<std::size_t>(val); } \
-    }                                                                       \
-
-  tr1_hashtable_define_trivial_hash(bool);
-  tr1_hashtable_define_trivial_hash(char);
-  tr1_hashtable_define_trivial_hash(signed char);
-  tr1_hashtable_define_trivial_hash(unsigned char);
-  tr1_hashtable_define_trivial_hash(wchar_t);
-  tr1_hashtable_define_trivial_hash(short);
-  tr1_hashtable_define_trivial_hash(int);
-  tr1_hashtable_define_trivial_hash(long);
-  tr1_hashtable_define_trivial_hash(unsigned short);
-  tr1_hashtable_define_trivial_hash(unsigned int);
-  tr1_hashtable_define_trivial_hash(unsigned long);
-
-  tr1_hashtable_define_trivial_hash(float);
-  tr1_hashtable_define_trivial_hash(double);
-  tr1_hashtable_define_trivial_hash(long double);
-
-  #undef tr1_hashtable_define_trivial_hash
-
-  template <typename T>
-    struct hash<T*> {
-      std::size_t operator()(T* p) const {
-        return reinterpret_cast<std::size_t>(p);
-      }
+  // Definition of default hash function std::tr1::hash<>.  The types for
+  // which std::tr1::hash<T> is defined is in clause 6.3.3. of the PDTR.
+  template<typename T>
+    struct hash;
+
+#define _TR1_hashtable_define_trivial_hash(_Tp)         \
+  template<>                                            \
+    struct hash<_Tp>                                    \
+    : public std::unary_function<_Tp, std::size_t>      \
+    {                                                   \
+      std::size_t                                       \
+      operator()(_Tp __val) const                       \
+      { return static_cast<std::size_t>(__val); }       \
+    }                                                     
+
+  _TR1_hashtable_define_trivial_hash(bool);
+  _TR1_hashtable_define_trivial_hash(char);
+  _TR1_hashtable_define_trivial_hash(signed char);
+  _TR1_hashtable_define_trivial_hash(unsigned char);
+  _TR1_hashtable_define_trivial_hash(wchar_t);
+  _TR1_hashtable_define_trivial_hash(short);
+  _TR1_hashtable_define_trivial_hash(int);
+  _TR1_hashtable_define_trivial_hash(long);
+  _TR1_hashtable_define_trivial_hash(unsigned short);
+  _TR1_hashtable_define_trivial_hash(unsigned int);
+  _TR1_hashtable_define_trivial_hash(unsigned long);
+
+#undef _TR1_hashtable_define_trivial_hash
+
+  template<typename _Tp>
+    struct hash<_Tp*>
+    : public std::unary_function<_Tp*, std::size_t>
+    {
+      std::size_t
+      operator()(_Tp* __p) const
+      { return reinterpret_cast<std::size_t>(__p); }
     };
 
-  // ??? We can probably find a better hash function than this (i.e. one
-  // that vectorizes better and that produces a more uniform distribution).
+  // Fowler / Noll / Vo (FNV) Hash (type FNV-1a)
+  // (used by the next specializations of std::tr1::hash<>)
 
-  // XXX String hash probably shouldn't be an inline member function,
-  // since it's nontrivial.  Once we have the framework for TR1 .cc
-  // files, this should go in one.
+  // Dummy generic implementation (for sizeof(size_t) != 4, 8).
+  template<std::size_t = sizeof(std::size_t)>
+    struct _Fnv_hash
+    {
+      static std::size_t
+      hash(const char* __first, std::size_t __length)
+      {
+       std::size_t __result = 0;
+       for (; __length > 0; --__length)
+         __result = (__result * 131) + *__first++;
+       return __result;
+      }
+    };
 
-  template <>
-    struct hash<std::string>
+  template<>
+    struct _Fnv_hash<4>
+    {
+      static std::size_t
+      hash(const char* __first, std::size_t __length)
+      {
+       std::size_t __result = static_cast<std::size_t>(2166136261UL);
+       for (; __length > 0; --__length)
+         {
+           __result ^= (std::size_t)*__first++;
+           __result *= 16777619UL;
+         }
+       return __result;
+      }
+    };
+  
+  template<>
+    struct _Fnv_hash<8>
     {
-      std::size_t operator()(const std::string& s) const
+      static std::size_t
+      hash(const char* __first, std::size_t __length)
       {
-        std::size_t result = 0;
-        for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
-          result = (result * 131) + *i;
-        return result;
+       std::size_t __result =
+         static_cast<std::size_t>(14695981039346656037ULL);
+       for (; __length > 0; --__length)
+         {
+           __result ^= (std::size_t)*__first++;
+           __result *= 1099511628211ULL;
+         }
+       return __result;
       }
     };
 
+  // XXX String and floating point hashes probably shouldn't be inline
+  // member functions, since are nontrivial.  Once we have the framework
+  // for TR1 .cc files, these should go in one.
+  template<>
+    struct hash<std::string>
+    : public std::unary_function<std::string, std::size_t>
+    {      
+      std::size_t
+      operator()(const std::string& __s) const
+      { return _Fnv_hash<>::hash(__s.data(), __s.length()); }
+    };
+
 #ifdef _GLIBCXX_USE_WCHAR_T
-  template <>
+  template<>
     struct hash<std::wstring>
+    : public std::unary_function<std::wstring, std::size_t>
     {
-      std::size_t operator()(const std::wstring& s) const
+      std::size_t
+      operator()(const std::wstring& __s) const
       {
-        std::size_t result = 0;
-        for (std::wstring::const_iterator i = s.begin(); i != s.end(); ++i)
-          result = (result * 131) + *i;
-        return result;
+       return _Fnv_hash<>::hash(reinterpret_cast<const char*>(__s.data()),
+                                __s.length() * sizeof(wchar_t));
       }
     };
 #endif
 
-}
+  template<>
+    struct hash<float>
+    : public std::unary_function<float, std::size_t>
+    {
+      std::size_t
+      operator()(float __fval) const
+      {
+       std::size_t __result = 0;
+
+       // 0 and -0 both hash to zero.
+       if (__fval != 0.0f)
+         __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__fval),
+                                      sizeof(__fval));
+       return __result;
+      }
+    };
+
+  template<>
+    struct hash<double>
+    : public std::unary_function<double, std::size_t>
+    {
+      std::size_t
+      operator()(double __dval) const
+      {
+       std::size_t __result = 0;
+
+       // 0 and -0 both hash to zero.
+       if (__dval != 0.0)
+         __result = _Fnv_hash<>::hash(reinterpret_cast<const char*>(&__dval),
+                                      sizeof(__dval));
+       return __result;
+      }
+    };
+
+  // For long double, careful with random padding bits (e.g., on x86,
+  // 10 bytes -> 12 bytes) and resort to frexp.
+  template<>
+    struct hash<long double>
+    : public std::unary_function<long double, std::size_t>
+    {
+      std::size_t
+      operator()(long double __ldval) const
+      {
+       std::size_t __result = 0;
+
+       int __exponent;
+       __ldval = std::frexp(__ldval, &__exponent);
+       __ldval = __ldval < 0.0l ? -(__ldval + 0.5l) : __ldval;
+
+       const long double __mult =
+         std::numeric_limits<std::size_t>::max() + 1.0l;
+       __ldval *= __mult;
+
+       // Try to use all the bits of the mantissa (really necessary only
+       // on 32-bit targets, at least for 80-bit floating point formats).
+       const std::size_t __hibits = (std::size_t)__ldval;
+       __ldval = (__ldval - (long double)__hibits) * __mult;
+
+       const std::size_t __coeff =
+         (std::numeric_limits<std::size_t>::max()
+          / std::numeric_limits<long double>::max_exponent);
+
+       __result = __hibits + (std::size_t)__ldval + __coeff * __exponent;
+
+       return __result;
+      }
+    };
+
+_GLIBCXX_END_NAMESPACE
 }
 
 #endif