diff --git a/libcxx/include/ext/__hash b/libcxx/include/ext/__hash
new file mode 100644
index 000000000000..8e9635d07f57
--- /dev/null
+++ b/libcxx/include/ext/__hash
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+//===------------------------- hash_set ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXT_HASH
+#define _LIBCPP_EXT_HASH
+
+#pragma GCC system_header
+
+#include <string>
+#include <cstring>
+
+namespace __gnu_cxx {
+using namespace std;
+
+template <typename T> struct _LIBCPP_VISIBLE hash : public std::hash<T>
+    { };
+
+template <> struct _LIBCPP_VISIBLE hash<const char*>
+    : public unary_function<const char*, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const char *__c) const _NOEXCEPT
+    {
+        return __do_string_hash(__c, __c + strlen(__c));
+    }
+};
+
+template <> struct _LIBCPP_VISIBLE hash<char *>
+    : public unary_function<char*, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char *__c) const _NOEXCEPT
+    {
+        return __do_string_hash<const char *>(__c, __c + strlen(__c));
+    }
+};
+}
+
+#endif _LIBCPP_EXT_HASH
diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index 21ce3be8a18c..9e62e7a777d6 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -203,6 +203,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 #include <__hash_table>
 #include <functional>
 #include <stdexcept>
+#include <ext/__hash>
 
 #if __DEPRECATED
 #warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
diff --git a/libcxx/include/ext/hash_set b/libcxx/include/ext/hash_set
index daad847afb35..14daf7bc29e4 100644
--- a/libcxx/include/ext/hash_set
+++ b/libcxx/include/ext/hash_set
@@ -196,6 +196,7 @@ template <class Value, class Hash, class Pred, class Alloc>
 #include <__config>
 #include <__hash_table>
 #include <functional>
+#include <ext/__hash>
 
 #if __DEPRECATED
 #warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
@@ -205,7 +206,7 @@ namespace __gnu_cxx {
 
 using namespace std;
 
-template <class _Value, class _Hash = std::hash<_Value>, class _Pred = equal_to<_Value>,
+template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
 class _LIBCPP_VISIBLE hash_set
 {
diff --git a/libcxx/include/string b/libcxx/include/string
index d1b9a5ea59ac..8d48e0af7d2f 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3857,6 +3857,21 @@ template<class _CharT, class _Traits, class _Allocator>
     const typename basic_string<_CharT, _Traits, _Allocator>::size_type
                    basic_string<_CharT, _Traits, _Allocator>::npos;
 
+template<class _Ptr>
+size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e)
+{
+    size_t __r = 0;
+    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
+    const size_t __m = size_t(0xF) << (__sr + 4);
+    for (; __p != __e; ++__p)
+    {
+        __r = (__r << 4) + *__p;
+        size_t __g = __r & __m;
+        __r ^= __g | (__g >> __sr);
+    }
+    return __r;
+}
+
 template<class _CharT, class _Traits, class _Allocator>
 struct _LIBCPP_VISIBLE hash<basic_string<_CharT, _Traits, _Allocator> >
     : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
@@ -3870,20 +3885,7 @@ size_t
 hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
         const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
 {
-    typedef basic_string<_CharT, _Traits, _Allocator> S;
-    typedef typename S::const_pointer const_pointer;
-    size_t __r = 0;
-    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
-    const size_t __m = size_t(0xF) << (__sr + 4);
-    const_pointer __p = __val.data();
-    const_pointer __e = __p + __val.size();
-    for (; __p != __e; ++__p)
-    {
-        __r = (__r << 4) + *__p;
-        size_t __g = __r & __m;
-        __r ^= __g | (__g >> __sr);
-    }
-    return __r;
+    return __do_string_hash(__val.data(), __val.data() + __val.size());
 }
 
 template<class _CharT, class _Traits, class _Allocator>