9 // This is a slow larval-stage kludge to help massage the generated man
10 // pages. It's used like this:
11 const std::string_view usage
= R
"(
12 Takes on stdin, whitespace-separated words of the form
17 and writes on stdout the nearest matching standard header name.
19 Takes no command-line arguments.
22 // List of standard headers
23 std::set
<std::string_view
> std_headers
;
24 // Map of partial header filenames to standard headers.
25 std::map
<std::string_view
, std::string_view
> headers
;
29 // Enter the glamourous world of data entry!! Maintain these!
30 // Because the map_header function removes common prefixes and suffixes,
31 // a header "bits/st[dl]_foo.h" will automatically map to "foo" if that
32 // is a standard header, so we don't need to list those cases here.
33 headers
["atomic_base.h"] = "atomic";
34 headers
["atomic_lockfree_defines.h"] = "atomic";
35 headers
["atomic_timed_wait.h"] = "atomic";
36 headers
["atomic_wait.h"] = "atomic";
37 headers
["algorithmfwd.h"] = "algorithm";
38 headers
["algo.h"] = "algorithm";
39 headers
["algobase.h"] = "algorithm";
40 headers
["ranges_algo.h"] = "algorithm";
41 headers
["ranges_algobase.h"] = "algorithm";
42 headers
["heap.h"] = "algorithm";
43 headers
["chrono_io.h"] = "chrono";
44 headers
["parse_numbers.h"] = "chrono";
45 headers
["exception_ptr.h"] = "exception";
46 headers
["nested_exception.h"] = "exception";
47 headers
["fs_dir.h"] = "filesystem";
48 headers
["fs_fwd.h"] = "filesystem";
49 headers
["fs_ops.h"] = "filesystem";
50 headers
["fs_path.h"] = "filesystem";
51 headers
["unicode.h"] = "format";
52 headers
["unicode-data.h"] = "format";
53 headers
["binders.h"] = "functional";
54 headers
["function.h"] = "functional";
55 headers
["functional_hash.h"] = "functional";
56 headers
["mofunc_impl.h"] = "functional";
57 headers
["move_only_function.h"] = "functional";
58 headers
["invoke.h"] = "functional";
59 headers
["ranges_cmp.h"] = "functional";
60 headers
["refwrap.h"] = "functional";
61 headers
["elements_of.h"] = "generator";
62 headers
["quoted_string.h"] = "iomanip";
63 headers
["ios_base.h"] = "ios";
64 headers
["basic_ios.h"] = "ios";
65 headers
["basic_ios.tcc"] = "ios";
66 headers
["iosfwd.h"] = "iosfwd";
67 headers
["iostream.h"] = "iostream";
68 headers
["iterator_base_funcs.h"] = "iterator";
69 headers
["iterator_base_types.h"] = "iterator";
70 headers
["stream_iterator.h"] = "iterator";
71 headers
["streambuf_iterator.h"] = "iterator";
72 headers
["iterator_concepts.h"] = "iterator";
73 headers
["max_size_type.h"] = "iterator";
74 headers
["range_access.h"] = "iterator";
75 headers
["codecvt.h"] = "locale";
76 headers
["c++locale.h"] = "locale";
77 headers
["localefwd.h"] = "locale";
78 headers
["ctype_base.h"] = "locale";
79 headers
["locale_classes.h"] = "locale";
80 headers
["locale_classes.tcc"] = "locale";
81 headers
["locale_facets.h"] = "locale";
82 headers
["locale_facets.tcc"] = "locale";
83 headers
["locale_facets_nonio.h"] = "locale";
84 headers
["locale_facets_nonio.tcc"] = "locale";
85 headers
["locale_conv.h"] = "locale";
86 headers
["multimap.h"] = "map";
87 headers
["memoryfwd.h"] = "memory";
88 headers
["align.h"] = "memory";
89 headers
["alloc_traits.h"] = "memory";
90 headers
["allocated_ptr.h"] = "memory";
91 headers
["auto_ptr.h"] = "memory";
92 headers
["construct.h"] = "memory";
93 headers
["allocator.h"] = "memory";
94 headers
["new_allocator.h"] = "memory";
95 headers
["raw_storage_iter.h"] = "memory";
96 headers
["tempbuf.h"] = "memory";
97 headers
["uninitialized.h"] = "memory";
98 headers
["shared_ptr.h"] = "memory";
99 headers
["shared_ptr_base.h"] = "memory";
100 headers
["shared_ptr_atomic.h"] = "memory";
101 headers
["unique_ptr.h"] = "memory";
102 headers
["ranges_uninitialized.h"] = "memory";
103 headers
["ptr_traits.h"] = "memory";
104 headers
["uses_allocator.h"] = "memory";
105 headers
["uses_allocator_args.h"] = "memory";
106 headers
["out_ptr.h"] = "memory";
107 headers
["memory_resource.h"] = "memory_resource";
108 headers
["unique_lock.h"] = "mutex";
109 headers
["sat_arith.h"] = "numeric";
110 headers
["ostream_insert.h"] = "ostream";
111 headers
["uniform_int_dist.h"] = "random";
112 headers
["ranges_base.h"] = "ranges";
113 headers
["ranges_to.h"] = "ranges";
114 headers
["ranges_util.h"] = "ranges";
115 headers
["regex_automaton.h"] = "regex";
116 headers
["regex_automaton.tcc"] = "regex";
117 headers
["regex_compiler.h"] = "regex";
118 headers
["regex_compiler.tcc"] = "regex";
119 headers
["regex_constants.h"] = "regex";
120 headers
["regex_error.h"] = "regex";
121 headers
["regex_executor.h"] = "regex";
122 headers
["regex_executor.tcc"] = "regex";
123 headers
["regex_scanner.h"] = "regex";
124 headers
["regex_scanner.tcc"] = "regex";
125 headers
["semaphore_base.h"] = "semaphore";
126 headers
["multiset.h"] = "set";
127 headers
["node_handle.h"] = "set";
128 headers
["functexcept.h"] = "stdexcept";
129 headers
["char_traits.h"] = "string";
130 headers
["stringfwd.h"] = "string";
131 headers
["postypes.h"] = "string";
132 headers
["basic_string.h"] = "string";
133 headers
["basic_string.tcc"] = "string";
134 headers
["cow_string.h"] = "string";
135 headers
["string_view.tcc"] = "string_view";
136 headers
["this_thread_sleep.h"] = "thread";
137 headers
["tree.h"] = "map";
138 headers
["hashtable.h"] = "unordered_map";
139 headers
["hashtable_policy.h"] = "unordered_map";
140 headers
["move.h"] = "utility";
141 headers
["pair.h"] = "utility";
142 headers
["relops.h"] = "utility";
143 headers
["gslice.h"] = "valarray";
144 headers
["gslice_array.h"] = "valarray";
145 headers
["indirect_array.h"] = "valarray";
146 headers
["mask_array.h"] = "valarray";
147 headers
["slice_array.h"] = "valarray";
148 headers
["valarray_after.h"] = "valarray";
149 headers
["valarray_before.h"] = "valarray";
150 headers
["valarray_array.h"] = "valarray";
151 headers
["valarray_array.tcc"] = "valarray";
152 headers
["valarray_meta.h"] = "valarray";
153 headers
["bvector.h"] = "vector";
155 //headers["concurrence.h"] who knows
156 //headers["atomicity.h"] who knows
158 headers
["abs.h"] = "cstdlib";
159 headers
["specfun.h"] = "cmath";
161 // This list is complete as of the April 2024 working draft.
163 "algorithm", "any", "array", "atomic",
164 "barrier", "bit", "bitset",
165 "charconv", "chrono", "codecvt", "compare", "complex",
166 "concepts", "condition_variable", "coroutine",
167 "debugging", "deque",
168 "exception", "execution", "expected",
169 "filesystem", "flat_set", "flat_map", "format", "forward_list",
170 "fstream", "functional", "future",
173 "initializer_list", "iomanip", "ios", "iosfwd",
174 "iostream", "istream", "iterator",
175 "latch", "limits", "linalg", "list", "locale",
176 "map", "mdspan", "memory", "memory_resource", "mutex",
177 "new", "numbers", "numeric",
178 "optional", "ostream",
181 "random", "ranges", "ratio", "rcu", "regex",
182 "scoped_allocator", "semaphore", "set", "shared_mutex",
183 "source_location", "span", "spanstream", "sstream",
184 "stack", "stacktrace", "stdexcept", "stdfloat", "stop_token",
185 "streambuf", "string", "string_view", "strstream",
186 "syncstream", "system_error",
187 "text_encoding", "thread", "tuple", "type_traits",
188 "typeindex", "typeinfo",
189 "unordered_map", "unordered_set", "utility",
190 "valarray", "variant", "vector", "version",
192 "cassert", "cctype", "cerrno", "cfenv", "cfloat",
193 "cinttypes", "climits", "clocale", "cmath", "csetjmp",
194 "csignal", "cstdarg", "cstddef", "cstdint", "cstdio",
195 "cstdlib", "cstring", "ctime", "cuchar", "cwchar",
198 "assert.h", "ctype.h", "errno.h", "fenv.h", "float.h",
199 "inttypes.h", "limits.h", "locale.h", "math.h", "setjmp.h",
200 "signal.h", "stdarg.h", "stddef.h", "stdint.h", "stdio.h",
201 "stdlib.h", "string.h", "time.h", "uchar.h", "wchar.h",
205 // In case we missed any:
206 for (const auto& h
: headers
)
207 std_headers
.insert(h
.second
);
211 std::string_view
map_header (std::string_view header
)
213 // if it doesn't contain a "." then it's already a std header
214 if (!header
.contains('.'))
216 // make sure it's in the set:
217 std_headers
.insert(header
);
221 for (std::string_view prefix
: {"bits/", "stl_", "std_"})
222 if (header
.starts_with(prefix
))
223 header
.remove_prefix(prefix
.size());
225 if (auto it
= headers
.find(header
); it
!= headers
.end())
228 for (std::string_view ext
: {".h", ".tcc"})
229 if (header
.ends_with(ext
))
231 header
.remove_suffix(ext
.size());
235 if (auto it
= std_headers
.find(header
); it
!= std_headers
.end())
241 std::string
map_header_or_complain (std::string header
)
243 // For <experimental/xxx.h> and <tr1/xxx.h> try to map <xxx.h>
244 // then add the directory back to it.
245 if (header
.contains('.'))
246 for (std::string_view dir
: {"experimental/", "tr1/"})
247 if (header
.starts_with(dir
))
249 auto h
= map_header(header
.substr(dir
.size()));
251 return std::string(dir
) + std::string(h
);
252 return std::string(header
);
255 if (auto mapped
= map_header(header
); !mapped
.empty())
256 return std::string(mapped
);
258 std::cerr
<< "Could not map <" << header
<< "> to a standard header\n";
259 return std::string(header
);
263 int main (int argc
, char** argv
)
267 std::cerr
<< "Usage: " << argv
[0] << '\n' << usage
;
273 std::transform(std::istream_iterator
<std::string
>(std::cin
), {},
274 std::ostream_iterator
<std::string
>(std::cout
),
275 map_header_or_complain
);