DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/* -*- 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 mAtomp;
};

// 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