LLVM 22.0.0git
StringTable.h
Go to the documentation of this file.
1//===- StringTable.h - Table of strings tracked by offset ----------C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_ADT_STRING_TABLE_H
10#define LLVM_ADT_STRING_TABLE_H
11
12#include "llvm/ADT/StringRef.h"
13#include "llvm/ADT/iterator.h"
14#include <cassert>
15#include <iterator>
16#include <limits>
17
18namespace llvm {
19
20/// A table of densely packed, null-terminated strings indexed by offset.
21///
22/// This table abstracts a densely concatenated list of null-terminated strings,
23/// each of which can be referenced using an offset into the table.
24///
25/// This requires and ensures that the string at offset 0 is also the empty
26/// string. This helps allow zero-initialized offsets form empty strings and
27/// avoids non-zero initialization when using a string literal pointer would
28/// allow a null pointer.
29///
30/// The primary use case is having a single global string literal for the table
31/// contents, and offsets into it in other global data structures to avoid
32/// dynamic relocations of individual string literal pointers in those global
33/// data structures.
35 StringRef Table;
36
37public:
38 // An offset into one of these packed string tables, used to select a string
39 // within the table.
40 //
41 // Typically these are created by TableGen or other code generator from
42 // computed offsets, and it just wraps that integer into a type until it is
43 // used with the relevant table.
44 //
45 // We also ensure that the empty string is at offset zero and default
46 // constructing this class gives you an offset of zero. This makes default
47 // constructing this type work similarly (after indexing the table) to default
48 // constructing a `StringRef`.
49 class Offset {
50 // Note that we ensure the empty string is at offset zero.
51 unsigned Value = 0;
52
53 public:
54 constexpr Offset() = default;
55 constexpr Offset(unsigned Value) : Value(Value) {}
56
57 friend constexpr bool operator==(const Offset &LHS, const Offset &RHS) {
58 return LHS.Value == RHS.Value;
59 }
60
61 friend constexpr bool operator!=(const Offset &LHS, const Offset &RHS) {
62 return LHS.Value != RHS.Value;
63 }
64
65 constexpr unsigned value() const { return Value; }
66 };
67
68 // We directly handle string literals with a templated converting constructor
69 // because we *don't* want to do `strlen` on them -- we fully expect null
70 // bytes in this input. This is somewhat the opposite of how `StringLiteral`
71 // works.
72 template <size_t N>
73 constexpr StringTable(const char (&RawTable)[N]) : Table(RawTable, N) {
74 static_assert(N <= std::numeric_limits<unsigned>::max(),
75 "We only support table sizes that can be indexed by an "
76 "`unsigned` offset.");
77
78 // Note that we can only use `empty`, `data`, and `size` in these asserts to
79 // support `constexpr`.
80 assert(!Table.empty() && "Requires at least a valid empty string.");
81 assert(Table.data()[0] == '\0' && "Offset zero must be the empty string.");
82 // Regardless of how many strings are in the table, the last one should also
83 // be null terminated. This also ensures that computing `strlen` on the
84 // strings can't accidentally run past the end of the table.
85 assert(Table.data()[Table.size() - 1] == '\0' &&
86 "Last byte must be a null byte.");
87 }
88
89 // Returns the raw C string from the table starting with the provided offset.
90 // The returned string is null terminated.
91 constexpr const char *getCString(Offset O) const {
92 assert(O.value() < Table.size() && "Out of bounds offset!");
93 return Table.data() + O.value();
94 }
95
96 // Get a string from the table starting with the provided offset. The returned
97 // `StringRef` is in fact null terminated, and so can be converted safely to a
98 // C-string if necessary for a system API.
99 constexpr StringRef operator[](Offset O) const { return getCString(O); }
100
101 /// Returns the byte size of the table.
102 constexpr size_t size() const { return Table.size(); }
103
104 class Iterator
105 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
106 const StringRef> {
107 friend StringTable;
108
109 const StringTable *Table;
110 Offset O;
111
112 // A cache of one value to allow `*` to return a reference.
113 mutable StringRef S;
114
115 explicit constexpr Iterator(const StringTable &Table, Offset O)
116 : Table(&Table), O(O) {}
117
118 public:
119 constexpr Iterator(const Iterator &RHS) = default;
120 constexpr Iterator(Iterator &&RHS) = default;
121
122 constexpr Iterator &operator=(const Iterator &RHS) = default;
123 constexpr Iterator &operator=(Iterator &&RHS) = default;
124
125 bool operator==(const Iterator &RHS) const {
126 assert(Table == RHS.Table && "Compared iterators for unrelated tables!");
127 return O == RHS.O;
128 }
129
130 const StringRef &operator*() const {
131 S = (*Table)[O];
132 return S;
133 }
134
135 Iterator &operator++() {
136 O = O.value() + (*Table)[O].size() + 1;
137 return *this;
138 }
139
140 Offset offset() const { return O; }
141 };
142
143 constexpr Iterator begin() const { return Iterator(*this, 0); }
144 constexpr Iterator end() const { return Iterator(*this, size() - 1); }
145};
146
147} // namespace llvm
148
149#endif // LLVM_ADT_STRING_TABLE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Value * RHS
Value * LHS
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool operator==(const Iterator &RHS) const
const StringRef & operator*() const
constexpr Iterator & operator=(const Iterator &RHS)=default
constexpr Iterator(Iterator &&RHS)=default
constexpr Iterator & operator=(Iterator &&RHS)=default
constexpr Iterator(const Iterator &RHS)=default
constexpr Offset(unsigned Value)
Definition StringTable.h:55
constexpr unsigned value() const
Definition StringTable.h:65
friend constexpr bool operator==(const Offset &LHS, const Offset &RHS)
Definition StringTable.h:57
friend constexpr bool operator!=(const Offset &LHS, const Offset &RHS)
Definition StringTable.h:61
constexpr Offset()=default
constexpr size_t size() const
Returns the byte size of the table.
constexpr StringRef operator[](Offset O) const
Definition StringTable.h:99
constexpr Iterator begin() const
constexpr Iterator end() const
constexpr const char * getCString(Offset O) const
Definition StringTable.h:91
constexpr StringTable(const char(&RawTable)[N])
Definition StringTable.h:73
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
This is an optimization pass for GlobalISel generic memory operations.
#define N