diff --git a/libstdc++-v3/doc/doxygen/stdheader.cc
b/libstdc++-v3/doc/doxygen/stdheader.cc
index 8bcb1a059f9..67f54eef02b 100644
--- a/libstdc++-v3/doc/doxygen/stdheader.cc
+++ b/libstdc++-v3/doc/doxygen/stdheader.cc
@@ -1,171 +1,256 @@
-// This is a slow larval-stage kludge to help massage the generated man
-// pages.  It's used like this:
-const char* const usage =
-"\nTakes on stdin, whitespace-separated words of the form\n"
-"\n"
-"    [bits/]stl_foo.h\n"
-"    [bits/]std_foo.h\n"
-"\n"
-"and writes on stdout the nearest matching standard header name.\n"
-"\n"
-"Takes no command-line arguments.\n"
-"\n";
-
-#include <cstdlib>
 #include <string>
+#include <string_view>
 #include <map>
+#include <set>
+#include <algorithm>
+#include <iterator>
 #include <iostream>

-typedef std::map<std::string, std::string>   Map;
+// This is a slow larval-stage kludge to help massage the generated man
+// pages.  It's used like this:
+const std::string_view usage = R"(
+Takes on stdin, whitespace-separated words of the form
+
+    [bits/]stl_foo.h
+    [bits/]std_foo.h
+
+and writes on stdout the nearest matching standard header name.

-Map  headers;
+Takes no command-line arguments.
+)";
+
+// List of standard headers
+std::set<std::string_view> std_headers;
+// Map of partial header filenames to standard headers.
+std::map<std::string_view, std::string_view>  headers;

 void init_map()
 {
     // Enter the glamourous world of data entry!!  Maintain these!
+    // Because the map_header function removes common prefixes and
suffixes,
+    // a header "bits/st[dl]_foo.h" will automatically map to "foo" if that
+    // is a standard header, so we don't need to list those cases here.
+    headers["atomic_base.h"]            = "atomic";
+    headers["atomic_lockfree_defines.h"] = "atomic";
+    headers["atomic_timed_wait.h"]      = "atomic";
+    headers["atomic_wait.h"]            = "atomic";
+    headers["algorithmfwd.h"]           = "algorithm";
     headers["algo.h"]                   = "algorithm";
     headers["algobase.h"]               = "algorithm";
-    headers["algorithm.h"]              = "algorithm";
+    headers["ranges_algo.h"]            = "algorithm";
+    headers["ranges_algobase.h"]        = "algorithm";
     headers["heap.h"]                   = "algorithm";
-    headers["bitset.h"]                 = "bitset";
-    headers["complex.h"]                = "complex";
-    //headers["construct.h"]              stl_construct.h entirely internal
-    headers["deque.h"]                  = "deque";
-    headers["deque.tcc"]                = "deque";
-    headers["fstream.h"]                = "fstream";
-    headers["fstream.tcc"]              = "fstream";
+    headers["exception_ptr.h"]          = "exception";
+    headers["nested_exception.h"]       = "exception";
+    headers["fs_dir.h"]                 = "filesystem";
+    headers["fs_fwd.h"]                 = "filesystem";
+    headers["fs_ops.h"]                 = "filesystem";
+    headers["fs_path.h"]                = "filesystem";
+    headers["binders.h"]                = "functional";
     headers["function.h"]               = "functional";
-    headers["functional.h"]             = "functional";
-    headers["iomanip.h"]                = "iomanip";
+    headers["functional_hash.h"]        = "functional";
+    headers["mofunc_impl.h"]            = "functional";
+    headers["move_only_function.h"]     = "functional";
+    headers["invoke.h"]                 = "functional";
+    headers["refwrap.h"]                = "functional";
+    headers["quoted_string.h"]          = "iomanip";
+    headers["ios_base.h"]               = "ios";
     headers["basic_ios.h"]              = "ios";
     headers["basic_ios.tcc"]            = "ios";
-    headers["ios.h"]                    = "ios";
     headers["iosfwd.h"]                 = "iosfwd";
     headers["iostream.h"]               = "iostream";
-    headers["istream.h"]                = "istream";
-    headers["istream.tcc"]              = "istream";
-    headers["iterator.h"]               = "iterator";
     headers["iterator_base_funcs.h"]    = "iterator";
     headers["iterator_base_types.h"]    = "iterator";
     headers["stream_iterator.h"]        = "iterator";
     headers["streambuf_iterator.h"]     = "iterator";
-    headers["limits.h"]                 = "limits";
-    headers["list.h"]                   = "list";
-    headers["list.tcc"]                 = "list";
+    headers["iterator_concepts.h"]      = "iterator";
+    headers["range_access.h"]           = "iterator";
     headers["codecvt.h"]                = "locale";
-    headers["locale.h"]                 = "locale";
+    headers["c++locale.h"]              = "locale";
     headers["localefwd.h"]              = "locale";
+    headers["ctype_base.h"]             = "locale";
     headers["locale_classes.h"]         = "locale";
+    headers["locale_classes.tcc"]       = "locale";
     headers["locale_facets.h"]          = "locale";
     headers["locale_facets.tcc"]        = "locale";
-    headers["map.h"]                    = "map";
+    headers["locale_facets_nonio.h"]    = "locale";
+    headers["locale_facets_nonio.tcc"]  = "locale";
+    headers["locale_conv.h"]            = "locale";
     headers["multimap.h"]               = "map";
-    headers["memory.h"]                 = "memory";
+    headers["memoryfwd.h"]              = "memory";
+    headers["align.h"]                  = "memory";
+    headers["alloc_traits.h"]           = "memory";
+    headers["auto_ptr.h"]              = "memory";
+    headers["construct.h"]              = "memory";
     headers["allocator.h"]              = "memory";
     headers["raw_storage_iter.h"]       = "memory";
     headers["tempbuf.h"]                = "memory";
     headers["uninitialized.h"]          = "memory";
-    headers["numeric.h"]                = "numeric";
-    headers["ostream.h"]                = "ostream";
-    headers["ostream.tcc"]              = "ostream";
-    headers["queue.h"]                  = "queue";
-    headers["set.h"]                    = "set";
+    headers["shared_ptr.h"]             = "memory";
+    headers["shared_ptr_base.h"]        = "memory";
+    headers["shared_ptr_atomic.h"]      = "memory";
+    headers["unique_ptr.h"]             = "memory";
+    headers["ranges_uninitialized.h"]   = "memory";
+    headers["ptr_traits.h"]             = "memory";
+    headers["uses_allocator.h"]         = "memory";
+    headers["uses_allocator_args.h"]    = "memory";
+    headers["unique_lock.h"]            = "mutex";
+    headers["uniform_int_dist.h"]       = "random";
+    headers["ranges_base.h"]            = "ranges";
+    headers["ranges_util.h"]            = "ranges";
+    headers["ranges_cmp.h"]             = "functional";
+    headers["regex_automaton.h"]        = "regex";
+    headers["regex_automaton.tcc"]      = "regex";
+    headers["regex_compiler.h"]         = "regex";
+    headers["regex_compiler.tcc"]       = "regex";
+    headers["regex_constants.h"]        = "regex";
+    headers["regex_error.h"]            = "regex";
+    headers["regex_executor.h"]         = "regex";
+    headers["regex_executor.tcc"]       = "regex";
+    headers["regex_scanner.h"]          = "regex";
+    headers["regex_scanner.tcc"]        = "regex";
+    headers["semaphore_base.h"]         = "semaphore";
     headers["multiset.h"]               = "set";
-    headers["sstream.h"]                = "sstream";
-    headers["sstream.tcc"]              = "sstream";
-    headers["stack.h"]                  = "stack";
+    headers["node_handle.h"]            = "set";
     headers["functexcept.h"]            = "stdexcept";
-    headers["stdexcept.h"]              = "stdexcept";
-    headers["streambuf.h"]              = "streambuf";
-    headers["streambuf.tcc"]            = "streambuf";
-    headers["string.h"]                 = "string";
     headers["char_traits.h"]            = "string";
+    headers["stringfwd.h"]              = "string";
     headers["postypes.h"]               = "string";
     headers["basic_string.h"]           = "string";
     headers["basic_string.tcc"]         = "string";
-    headers["tree.h"]                   = "backward/tree.h";
+    headers["cow_string.h"]             = "string";
+    headers["string_view.tcc"]          = "string_view";
+    headers["this_thread_sleep.h"]      = "thread";
+    headers["tree.h"]                   = "map";
     headers["pair.h"]                   = "utility";
-    headers["utility.h"]                = "utility";
     headers["relops.h"]                 = "utility";
     headers["gslice.h"]                 = "valarray";
     headers["gslice_array.h"]           = "valarray";
     headers["indirect_array.h"]         = "valarray";
     headers["mask_array.h"]             = "valarray";
     headers["slice_array.h"]            = "valarray";
-    headers["valarray.h"]               = "valarray";
     headers["valarray_after.h"]         = "valarray";
     headers["valarray_before.h"]        = "valarray";
     headers["valarray_array.h"]         = "valarray";
     headers["valarray_array.tcc"]       = "valarray";
     headers["valarray_meta.h"]          = "valarray";
     headers["bvector.h"]                = "vector";
-    headers["vector.h"]                 = "vector";
-    headers["vector.tcc"]               = "vector";

     //headers["concurrence.h"]             who knows
     //headers["atomicity.h"]               who knows

-    // C wrappers -- probably was an easier way to do these, but oh well
-    headers["cassert.h"]                = "cassert";
-    headers["cctype.h"]                 = "cctype";
-    headers["cerrno.h"]                 = "cerrno";
-    headers["cfloat.h"]                 = "cfloat";
-    headers["climits.h"]                = "climits";
-    headers["clocale.h"]                = "clocale";
-    headers["cmath.h"]                  = "cmath";
-    headers["csetjmp.h"]                = "csetjmp";
-    headers["csignal.h"]                = "csignal";
-    headers["cstdarg.h"]                = "cstdarg";
-    headers["cstddef.h"]                = "cstddef";
-    headers["cstdio.h"]                 = "cstdio";
-    headers["cstdlib.h"]                = "cstdlib";
-    headers["cstring.h"]                = "cstring";
-    headers["ctime.h"]                  = "ctime";
-    headers["cwchar.h"]                 = "cwchar";
-    headers["cwctype.h"]                = "cwctype";
+    headers["abs.h"]                    = "cstdlib";
+    headers["specfun.h"]                = "cmath";
+
+    // This list is complete as of the October 2021 working draft.
+    std_headers = {
+       "algorithm", "any", "array", "atomic",
+       "barrier", "bit", "bitset",
+       "charconv", "chrono", "codecvt", "compare", "complex",
+       "concepts", "condition_variable", "coroutine",
+       "deque",
+       "exception", "execution",
+       "filesystem", "format", "forward_list", "fstream",
+       "functional", "future",
+       "initializer_list", "iomanip", "ios", "iosfwd",
+       "iostream", "istream", "iterator",
+       "latch", "limits", "list", "locale",
+       "map", "memory", "memory_resource", "mutex",
+       "new", "numbers", "numeric",
+       "optional", "ostream",
+       "queue",
+       "random", "ranges", "ratio", "regex",
+       "scoped_allocator", "semaphore", "set", "shared_mutex",
+       "source_location", "span", "spanstream", "sstream",
+       "stack", "stacktrace", "stdexcept", "stop_token",
+       "streambuf", "string", "string_view", "strstream",
+       "syncstream", "system_error",
+       "thread", "tuple", "typeindex", "typeinfo", "type_traits",
+       "unordered_map", "unordered_set", "utility",
+       "valarray", "variant", "vector", "version",
+
+       "cassert", "cctype", "cerrno", "cfenv", "cfloat",
+       "cinttypes", "climits", "clocale", "cmath", "csetjmp",
+       "csignal", "cstdarg", "cstddef", "cstdint", "cstdio",
+       "cstdlib", "cstring", "ctime", "cuchar", "cwchar",
+       "cwctype",
+
+       "assert.h", "ctype.h", "errno.h", "fenv.h", "float.h",
+       "inttypes.h", "limits.h", "locale.h", "math.h", "setjmp.h",
+       "signal.h", "stdarg.h", "stddef.h", "stdint.h", "stdio.h",
+       "stdlib.h", "string.h", "time.h", "uchar.h", "wchar.h",
+       "wctype.h",
+    };
+
+    // In case we missed any:
+    for (const auto& h : headers)
+       std_headers.insert(h.second);
 }


-void do_word (std::string const& longheader)
+std::string_view map_header (std::string_view header)
 {
-    std::string::size_type start = 0;
-
     // if it doesn't contain a "." then it's already a std header
-    if (longheader.find(".") == std::string::npos)
+    if (!header.contains('.'))
     {
-        std::cout << longheader << '\n';
-        return;
+       // make sure it's in the set:
+       std_headers.insert(header);
+       return header;
     }

-    if (longheader.substr(start,5) == "bits/")  start += 5;
-    if ((longheader.substr(start,4) == "stl_") ||
-        (longheader.substr(start,4) == "std_"))
-    {
-        start += 4;
-    }
+    for (std::string_view prefix : {"bits/", "stl_", "std_"})
+       if (header.starts_with(prefix))
+           header.remove_prefix(prefix.size());
+
+    if (auto it = headers.find(header); it != headers.end())
+       return it->second;
+
+    for (std::string_view ext : {".h", ".tcc"})
+       if (header.ends_with(ext))
+       {
+           header.remove_suffix(ext.size());
+           break;
+       }
+
+    if (auto it = std_headers.find(header); it != std_headers.end())
+       return *it;
+
+    return {};
+}
+
+std::string map_header_or_complain (std::string header)
+{
+    // For <experimental/xxx.h> and <tr1/xxx.h> try to map <xxx.h>
+    // then add the directory back to it.
+    if (header.contains('.'))
+       for (std::string_view dir : {"experimental/", "tr1/"})
+           if (header.starts_with(dir))
+           {
+               auto h = map_header(header.substr(dir.size()));
+               if (!h.empty())
+                   return std::string(dir) + std::string(h);
+               return std::string(header);
+           }

-    // come on, gdb, find `p' already...
-    const char* p = longheader.substr(start).c_str();
-    Map::iterator word = headers.find(p);
-    if (word != headers.end())
-        std::cout << word->second << '\n';
-    else std::cout << "MAYBE_AN_ERROR_MESSAGE_HERE\n";
+    if (auto mapped = map_header(header); !mapped.empty())
+       return std::string(mapped);
+
+    std::cerr << "Could not map <" << header << "> to a standard header\n";
+    return std::string(header);
 }


-int main (int argc, char**)
+int main (int argc, char** argv)
 {
     if (argc > 1)
     {
-        std::cerr << usage;
-       std::exit(0);
+        std::cerr << "Usage: " << argv[0] << '\n' << usage;
+       return 1;
     }

     init_map();

-    std::string w;
-    while (std::cin >> w)
-        do_word (w);
+    std::transform(std::istream_iterator<std::string>(std::cin), {},
+                  std::ostream_iterator<std::string>(std::cout),
+                  map_header_or_complain);
 }
-
-
diff --git a/libstdc++-v3/scripts/run_doxygen
b/libstdc++-v3/scripts/run_doxygen
index a36772128ec..6236a071b1a 100644
--- a/libstdc++-v3/scripts/run_doxygen
+++ b/libstdc++-v3/scripts/run_doxygen
@@ -269,6 +269,8 @@ find . -name "* *" -print0 | xargs -0r rm        #
requires GNU tools

 # man pages are for functions/types/other entities, not source files
 # directly.  who the heck would type "man foo.h" anyhow?
+# FIXME: This also removes std.3 which is the only place that a lot of
+# functions are documented. Should we keep it?
 find . -name "[a-z]*" -a ! -name "std_*" -print | xargs rm
 rm -f *.h.3 *.hpp.3 *config* *.cc.3 *.tcc.3 *_t.3
