gecko-dev/xpcom/ds/nsStaticAtom.h

130 строки
4.4 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 nsStaticAtom_h__
#define nsStaticAtom_h__
#include <stdint.h>
class nsStaticAtom;
// The following macros are used to define static atoms, typically in
// conjunction with a .h file that defines the names and values of the atoms.
//
// For example, the .h file might be called MyAtomList.h and look like this:
//
// MY_ATOM(one, "one")
// MY_ATOM(two, "two")
// MY_ATOM(three, "three")
//
// The code defining the static atoms might look like this:
//
// class MyAtoms {
// public:
// #define MY_ATOM(_name, _value) NS_STATIC_ATOM_DECL(_name)
// #include "MyAtomList.h"
// #undef MY_ATOM
// };
//
// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_DEFN(MyAtoms, name_)
// #include "MyAtomList.h"
// #undef MY_ATOM
//
// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_, value_)
// #include "MyAtomList.h"
// #undef MY_ATOM
//
// static const nsStaticAtomSetup sMyAtomSetup[] = {
// #define MY_ATOM(name_, value_) NS_STATIC_ATOM_SETUP(MyAtoms, name_)
// #include "MyAtomList.h"
// #undef MY_ATOM
// };
//
// The macros expand to the following:
//
// class MyAtoms
// {
// public:
// static nsStaticAtom* one;
// static nsStaticAtom* two;
// static nsStaticAtom* three;
// };
//
// nsStaticAtom* MyAtoms::one;
// nsStaticAtom* MyAtoms::two;
// nsStaticAtom* MyAtoms::three;
//
// static const char16_t one_buffer[4] = u"one"; // plus a static_assert
// static const char16_t two_buffer[4] = u"two"; // plus a static_assert
// static const char16_t three_buffer[6] = u"three"; // plus a static_assert
//
// static const nsStaticAtomSetup sMyAtomSetup[] = {
// { one_buffer, &MyAtoms::one },
// { two_buffer, &MyAtoms::two },
// { three_buffer, &MyAtoms::three },
// };
//
// When RegisterStaticAtoms(sMyAtomSetup) is called it iterates over
// sMyAtomSetup[]. E.g. for the first atom it does roughly the following:
// - MyAtoms::one = new nsStaticAtom(one_buffer)
// - inserts MyAtoms::one into the atom table
// The declaration of the pointer to the static atom, which must be within a
// class.
#define NS_STATIC_ATOM_DECL(name_) \
static nsStaticAtom* name_;
// Like NS_STATIC_ATOM_DECL, but for sub-classes of nsStaticAtom.
#define NS_STATIC_ATOM_SUBCLASS_DECL(type_, name_) \
static type_* name_;
// The definition of the pointer to the static atom. Initially null, it is
// set by RegisterStaticAtoms() to point to a heap-allocated nsStaticAtom.
#define NS_STATIC_ATOM_DEFN(class_, name_) \
nsStaticAtom* class_::name_;
// Like NS_STATIC_ATOM_DEFN, but for sub-classes of nsStaticAtom.
#define NS_STATIC_ATOM_SUBCLASS_DEFN(type_, class_, name_) \
type_* class_::name_;
// The buffer of 16-bit chars that constitute the static atom.
//
// Note that |value_| is an 8-bit string, and so |sizeof(value_)| is equal
// to the number of chars (including the terminating '\0'). The |u""| prefix
// converts |value_| to a 16-bit string, which is what is assigned.
#define NS_STATIC_ATOM_BUFFER(name_, value_) \
static const char16_t name_##_buffer[sizeof(value_)] = u"" value_; \
static_assert(sizeof(value_[0]) == 1, "non-8-bit static atom literal");
// The StaticAtomSetup. Used only during start-up.
#define NS_STATIC_ATOM_SETUP(class_, name_) \
{ name_##_buffer, &class_::name_ },
// Like NS_STATIC_ATOM_SUBCLASS, but for sub-classes of nsStaticAtom.
#define NS_STATIC_ATOM_SUBCLASS_SETUP(class_, name_) \
{ name_##_buffer, reinterpret_cast<nsStaticAtom**>(&class_::name_) },
// Holds data used to initialize large number of atoms during startup. Use
// NS_STATIC_ATOM_SETUP to initialize these structs. They should never be
// accessed directly other than from nsAtomTable.cpp.
struct nsStaticAtomSetup
{
const char16_t* const mString;
nsStaticAtom** const mAtom;
};
// Register an array of static atoms with the atom table.
template<uint32_t N>
void
NS_RegisterStaticAtoms(const nsStaticAtomSetup (&aSetup)[N])
{
extern void RegisterStaticAtoms(const nsStaticAtomSetup* aSetup,
uint32_t aCount);
RegisterStaticAtoms(aSetup, N);
}
#endif