libabigail
abg-interned-str.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2016-2025 Red Hat, Inc.
5//
6// Author: Dodji Seketeli
7
8/// @file
9///
10/// Declaration of types pertaining to the interned string pool used
11/// throughout Libabigail, for performance reasons.
12///
13/// For the record, the concept of the String Interning method is
14/// explained at https://en.wikipedia.org/wiki/String_interning.
15
16#ifndef __ABG_INTERNED_STR_H__
17#define __ABG_INTERNED_STR_H__
18
19#include <functional>
20#include <memory>
21#include <ostream>
22#include <string>
23#include <unordered_set>
24
25
26namespace abigail
27{
28// Inject some std types into this namespace.
29using std::unordered_set;
30using std::string;
31using std::ostream;
32
33/// The abstraction of an interned string.
34///
35/// It's a wrapper around a pointer to a std::string, along with a set
36/// of method that helps make this string integrate with std::string
37/// seamlessly. For instance, the type provides equality operators
38/// that help compare it against std::string.
39///
40/// Note that this @ref interned_string type is design to have the
41/// same size as a pointer to a string.
43{
44 std::string* raw_;
45
46 /// Constructor.
47 ///
48 /// @param raw the pointer to string that this interned_string
49 /// wraps.
50 interned_string(string* raw)
51 : raw_(raw)
52 {}
53
54public:
55
56 /// Default constructor.
57 ///
58 /// Constructs an empty pointer to string.
60 : raw_()
61 {}
62
63 /// Copy constructor.
64 ///
65 /// @param o the other instance to copy from.
67 {raw_ = o.raw_;}
68
69 /// Assignment operator.
70 ///
71 /// @param o the other instance to assign to the current one.
74 {
75 raw_ = o.raw_;
76 return *this;
77 }
78
79 /// Clear the string.
80 void
82 {raw_ = 0;}
83
84 /// Test if the current instance of @ref interned_string is empty.
85 ///
86 /// @return true iff the currentisntance of @ref interned_string is
87 /// empty.
88 bool
89 empty() const
90 {return !raw_;}
91
92 /// Return the underlying pointer to std::string that this
93 /// interned_string wraps.
94 ///
95 /// @return a pointer to the underlying std::string, or 0 if this
96 /// interned_string is empty.
97 const string*
98 raw() const
99 {return raw_;}
100
101 /// Compare the current instance of @ref interned_string against
102 /// another instance of @ref interned_string.
103 ///
104 /// Note that this comparison is done in O(1), because it compares
105 /// the pointer values of the two underlying pointers to std::string
106 /// held by each instances of @ref interned_string.
107 ///
108 /// @param o the other @ref interned_string to compare against.
109 ///
110 /// @return true iff the current instance equals @p o.
111 bool
113 {return raw_ == o.raw_;}
114
115 /// Inequality operator.
116 ///
117 /// @param o the other @ref interned_string to compare the current
118 /// instance against.
119 ///
120 /// @return true iff the current instance is different from the @p
121 /// o.
122 bool
124 {return !operator==(o);}
125
126 /// Compare the current instance of @ref interned_string against
127 /// an instance of std::string.
128 ///
129 /// Note that this comparison is done in O(N), N being the size (in
130 /// number of characters) of the strings being compared.
131 ///
132 /// @param o the instance of std::string to compare against.
133 ///
134 /// @return true iff the current instance equals @p o.
135 bool
136 operator==(const string& o) const
137 {
138 if (raw_)
139 return *raw_ == o;
140 return o.empty();
141 }
142
143 /// Inequality operator.
144 ///
145 /// Takes the current instance of @ref interned_string and an
146 /// instance of std::string.
147 ///
148 /// @param o the instance of std::string to compare the current
149 /// instance of @ref interned_string against.
150 ///
151 /// @return true if the current instance of @ref interned_string is
152 /// different from @p o.
153 bool
154 operator!=(const string& o) const
155 {return ! operator==(o);}
156
157 /// "Less than" operator.
158 ///
159 /// Lexicographically compares the current instance of @ref
160 /// interned_string against another instance.
161 ///
162 /// @param o the other instance of @ref interned_string to compare
163 /// against.
164 ///
165 /// @return true iff the current instance of interned_string is
166 /// lexicographycally less than the string @p o.
167 bool
168 operator<(const interned_string& o) const
169 {return static_cast<string>(*this) < static_cast<std::string>(o);}
170
171 /// Conversion operator to string.
172 ///
173 /// @return the underlying string this instance refers too.
174 operator string() const
175 {
176 if (!raw_)
177 return "";
178 return *raw_;
179 }
180
181 friend class interned_string_pool;
182}; // end class interned_string
183
184bool
185operator==(const string& l, const interned_string& r);
186
187bool
188operator!=(const string& l, const interned_string& r);
189
190ostream&
191operator<<(ostream& o, const interned_string& s);
192
193string
194operator+(const interned_string& s1,const string& s2);
195
196string
197operator+(const string& s1, const interned_string& s2);
198
199/// A functor to hash instances of @ref interned_string.
201{
202 /// The hash operator.
203 ///
204 /// It's super fast because hashing an interned string amounts to
205 /// hashing the pointer to it's underlying string. It's because
206 /// every distinct string is present only in one copy in the
207 /// environment.
208 ///
209 /// @param s the instance of @ref interned_string to hash.
210 ///
211 /// @return the returned hash value.
212 size_t
214 {
215 std::hash<size_t> hash_size_t;
216 return hash_size_t(reinterpret_cast<size_t>(s.raw()));
217 }
218}; // end struct hash_interned_string
219
220
221/// The interned string pool.
222///
223/// This is where all the distinct strings represented by the interned
224/// strings leave. The pool is the actor responsible for creating
225/// interned strings.
227{
228 struct priv;
229 std::unique_ptr<priv> priv_;
230
231public:
232
234
236 create_string(const std::string&);
237
238 bool
239 has_string(const char* s) const;
240
241 const char*
242 get_string(const char* s) const;
243
245}; // end class interned_string_pool
246
247/// Convenience typedef for a set of @ref interned_string
248typedef unordered_set<interned_string,
250
251} // end namespace abigail
252
253#endif // __ABG_INTERNED_STR_H__
The interned string pool.
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
Definition: abg-ir.cc:96
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition: abg-ir.cc:106
interned_string create_string(const std::string &)
Create an interned string with a given value.
Definition: abg-ir.cc:123
interned_string_pool()
Default constructor.
Definition: abg-ir.cc:83
~interned_string_pool()
Destructor.
Definition: abg-ir.cc:132
The abstraction of an interned string.
bool operator<(const interned_string &o) const
"Less than" operator.
interned_string()
Default constructor.
const string * raw() const
Return the underlying pointer to std::string that this interned_string wraps.
bool operator==(const string &o) const
Compare the current instance of interned_string against an instance of std::string.
bool empty() const
Test if the current instance of interned_string is empty.
interned_string & operator=(const interned_string &o)
Assignment operator.
bool operator!=(const string &o) const
Inequality operator.
interned_string(const interned_string &o)
Copy constructor.
void clear()
Clear the string.
bool operator!=(const interned_string &o) const
Inequality operator.
bool operator==(const interned_string &o) const
Compare the current instance of interned_string against another instance of interned_string.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition: abg-ir.cc:151
unordered_set< interned_string, hash_interned_string > interned_string_set_type
Convenience typedef for a set of interned_string.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition: abg-ir.cc:185
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
Definition: abg-ir.cc:168
A functor to hash instances of interned_string.
size_t operator()(const interned_string &s) const
The hash operator.