зеркало из https://github.com/mozilla/gecko-dev.git
103 строки
4.1 KiB
C
103 строки
4.1 KiB
C
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
|
||
|
#ifndef XPCOM_THREADS_STATICSTRING_H_
|
||
|
#define XPCOM_THREADS_STATICSTRING_H_
|
||
|
|
||
|
#include <cstddef>
|
||
|
#include "mozilla/Attributes.h"
|
||
|
|
||
|
// from "nsStringFwd.h"
|
||
|
template <typename T>
|
||
|
class nsTLiteralString;
|
||
|
using nsLiteralCString = nsTLiteralString<char>;
|
||
|
|
||
|
namespace mozilla {
|
||
|
// class StaticString
|
||
|
//
|
||
|
// Wrapper type containing a C-style string which is guaranteed[*] to have been
|
||
|
// created (potentially indirectly) from static data. Primarily intended for
|
||
|
// text that may eventually be sent up via telemetry, to avoid the possibility
|
||
|
// of accidentally exfiltrating PII.
|
||
|
//
|
||
|
// `StaticString`, like `template <size_t N> const char (&str)[N]`, can be
|
||
|
// freely and implicitly converted to `const char *`, to simplify its use as a
|
||
|
// drop-in replacement when detemplatizing functions.
|
||
|
//
|
||
|
// ### Comparison/contrast with `nsLiteralCString`
|
||
|
//
|
||
|
// Concretely, `StaticString` is smaller than `nsLiteralCString`, as it does not
|
||
|
// store the string-length. It's also trivial to construct a `StaticString` from
|
||
|
// the variable `__func__` or the preprocessor token `__FILE__`, which would
|
||
|
// require additional work to be used with the latter's `_ns` constructor.
|
||
|
//
|
||
|
// Conventionally, the primary intended use case of `StaticString` is subtly
|
||
|
// different from that of `nsLiteralCString`:
|
||
|
// * `StaticString` is intended for correctness (etc.) in contexts where the
|
||
|
// consumer of the string requires that it be static.
|
||
|
// * `nsLiteralCString` is more for efficiency in contexts where the source
|
||
|
// string _happens to be_ static, but in which the consumer does not care
|
||
|
// (and so accepts `nsACString const &` or similar).
|
||
|
//
|
||
|
// This is not a hard rule, however, and is notably bent in dom::Promise. (See
|
||
|
// comments below.)
|
||
|
//
|
||
|
// Both are trivially-copyable/-movable/-destructible, guaranteed non-null, and
|
||
|
// can only contain static data.
|
||
|
//
|
||
|
// #### Footnotes
|
||
|
//
|
||
|
// [*] ```
|
||
|
// CHORUS: "What, never?"
|
||
|
// CAPTAIN: "Well... hardly ever!"
|
||
|
// CHORUS: "He's hardly ever sick of C!"
|
||
|
// -- Gilbert & Sullivan, _H.M.S. Pinafore_ (emended)
|
||
|
// ```
|
||
|
//
|
||
|
class StaticString {
|
||
|
/* TODO(C++20): convert `constexpr` to `consteval` wherever possible. */
|
||
|
const char* mStr; // guaranteed nonnull
|
||
|
|
||
|
public:
|
||
|
template <size_t N>
|
||
|
constexpr MOZ_IMPLICIT StaticString(const char (&str)[N]) : mStr(str) {}
|
||
|
|
||
|
// `nsLiteralCString` has the same guarantees as `StaticString` (both in being
|
||
|
// nonnull and containing only static data), so it's safe to construct either
|
||
|
// from the other.
|
||
|
//
|
||
|
// At present we only support construction of a `StaticString` from an
|
||
|
// `nsLiteralCString`, since this is zero-cost (the converse would not be),
|
||
|
// and is probably the simplest way to support dom::Promise's interoperation
|
||
|
// with MozPromise.
|
||
|
//
|
||
|
// (A more principled approach, in some sense, would be to create a third type
|
||
|
// `StaticStringWithLength` (or whatever) acting as the lattice-join of the
|
||
|
// two, which could then decay to either one as necessary. This is overkill
|
||
|
// for our current goals... but might be worthwhile if, _e.g._, you really
|
||
|
// need to get `__func__` into an `nsLiteralCString` rather than just an
|
||
|
// `nsDependentCString` for some reason.)
|
||
|
//
|
||
|
constexpr explicit StaticString(nsLiteralCString const& str);
|
||
|
|
||
|
constexpr StaticString(StaticString const&) = default;
|
||
|
constexpr StaticString(StaticString&&) = default;
|
||
|
~StaticString() = default;
|
||
|
|
||
|
constexpr MOZ_IMPLICIT operator const char*() const { return mStr; }
|
||
|
|
||
|
// Not normally needed, but useful for variadic logging functions.
|
||
|
constexpr const char* get() const { return mStr; }
|
||
|
};
|
||
|
|
||
|
// Under the covers, StaticString is as lightweight as a single pointer: it does
|
||
|
// not store the length of its deta.
|
||
|
static_assert(sizeof(StaticString) == sizeof(const char*));
|
||
|
static_assert(alignof(StaticString) == alignof(const char*));
|
||
|
} // namespace mozilla
|
||
|
|
||
|
#endif
|