Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / xpcom / threads / StaticString.h
blob26c8675b2496c38d462d4e4c0bde3e1c56a1951b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef XPCOM_THREADS_STATICSTRING_H_
8 #define XPCOM_THREADS_STATICSTRING_H_
10 #include <cstddef>
11 #include "mozilla/Attributes.h"
13 // from "nsStringFwd.h"
14 template <typename T>
15 class nsTLiteralString;
16 using nsLiteralCString = nsTLiteralString<char>;
18 namespace mozilla {
19 // class StaticString
21 // Wrapper type containing a C-style string which is guaranteed[*] to have been
22 // created (potentially indirectly) from static data. Primarily intended for
23 // text that may eventually be sent up via telemetry, to avoid the possibility
24 // of accidentally exfiltrating PII.
26 // `StaticString`, like `template <size_t N> const char (&str)[N]`, can be
27 // freely and implicitly converted to `const char *`, to simplify its use as a
28 // drop-in replacement when detemplatizing functions.
30 // ### Comparison/contrast with `nsLiteralCString`
32 // Concretely, `StaticString` is smaller than `nsLiteralCString`, as it does not
33 // store the string-length. It's also trivial to construct a `StaticString` from
34 // the variable `__func__` or the preprocessor token `__FILE__`, which would
35 // require additional work to be used with the latter's `_ns` constructor.
37 // Conventionally, the primary intended use case of `StaticString` is subtly
38 // different from that of `nsLiteralCString`:
39 // * `StaticString` is intended for correctness (etc.) in contexts where the
40 // consumer of the string requires that it be static.
41 // * `nsLiteralCString` is more for efficiency in contexts where the source
42 // string _happens to be_ static, but in which the consumer does not care
43 // (and so accepts `nsACString const &` or similar).
45 // This is not a hard rule, however, and is notably bent in dom::Promise. (See
46 // comments below.)
48 // Both are trivially-copyable/-movable/-destructible, guaranteed non-null, and
49 // can only contain static data.
51 // #### Footnotes
53 // [*] ```
54 // CHORUS: "What, never?"
55 // CAPTAIN: "Well... hardly ever!"
56 // CHORUS: "He's hardly ever sick of C!"
57 // -- Gilbert & Sullivan, _H.M.S. Pinafore_ (emended)
58 // ```
60 class StaticString {
61 /* TODO(C++20): convert `constexpr` to `consteval` wherever possible. */
62 const char* mStr; // guaranteed nonnull
64 public:
65 template <size_t N>
66 constexpr MOZ_IMPLICIT StaticString(const char (&str)[N]) : mStr(str) {}
68 // `nsLiteralCString` has the same guarantees as `StaticString` (both in being
69 // nonnull and containing only static data), so it's safe to construct either
70 // from the other.
72 // At present we only support construction of a `StaticString` from an
73 // `nsLiteralCString`, since this is zero-cost (the converse would not be),
74 // and is probably the simplest way to support dom::Promise's interoperation
75 // with MozPromise.
77 // (A more principled approach, in some sense, would be to create a third type
78 // `StaticStringWithLength` (or whatever) acting as the lattice-join of the
79 // two, which could then decay to either one as necessary. This is overkill
80 // for our current goals... but might be worthwhile if, _e.g._, you really
81 // need to get `__func__` into an `nsLiteralCString` rather than just an
82 // `nsDependentCString` for some reason.)
84 constexpr explicit StaticString(nsLiteralCString const& str);
86 constexpr StaticString(StaticString const&) = default;
87 constexpr StaticString(StaticString&&) = default;
88 ~StaticString() = default;
90 constexpr MOZ_IMPLICIT operator const char*() const { return mStr; }
92 // Not normally needed, but useful for variadic logging functions.
93 constexpr const char* get() const { return mStr; }
96 // Under the covers, StaticString is as lightweight as a single pointer: it does
97 // not store the length of its deta.
98 static_assert(sizeof(StaticString) == sizeof(const char*));
99 static_assert(alignof(StaticString) == alignof(const char*));
100 } // namespace mozilla
102 #endif