|  | /* String-interning set | 
|  |  | 
|  | Copyright (C) 2025 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #ifndef GDBSUPPORT_STRING_SET_H | 
|  | #define GDBSUPPORT_STRING_SET_H | 
|  |  | 
|  | #include "gdbsupport/unordered_set.h" | 
|  | #include <string_view> | 
|  |  | 
|  | namespace gdb | 
|  | { | 
|  |  | 
|  | /* This is a string-interning set.  It manages storage for strings, | 
|  | ensuring that just a single copy of a given string is kept.  The | 
|  | underlying C string will remain valid for the lifetime of this | 
|  | object.  */ | 
|  |  | 
|  | class string_set | 
|  | { | 
|  | public: | 
|  |  | 
|  | /* Insert STR into this set.  Returns a pointer to the interned | 
|  | string.  */ | 
|  | const char *insert (const char *str) | 
|  | { | 
|  | /* We need to take the length to hash the string anyway, so it's | 
|  | convenient to just wrap it here.  */ | 
|  | return insert (std::string_view (str)); | 
|  | } | 
|  |  | 
|  | /* An overload accepting a string view.  */ | 
|  | const char *insert (std::string_view str) | 
|  | { | 
|  | return m_set.insert (str).first->get (); | 
|  | } | 
|  |  | 
|  | /* An overload that takes ownership of the string.  */ | 
|  | const char *insert (gdb::unique_xmalloc_ptr<char> str) | 
|  | { | 
|  | return m_set.insert (local_string (std::move (str))).first->get (); | 
|  | } | 
|  |  | 
|  | private: | 
|  |  | 
|  | /* The type of string we store.  Note that we do not store | 
|  | std::string here to avoid the small-string optimization | 
|  | invalidating a pointer on rehash.  */ | 
|  | struct local_string | 
|  | { | 
|  | explicit local_string (std::string_view str) | 
|  | : contents (xstrndup (str.data (), str.size ())), | 
|  | len (str.size ()) | 
|  | { } | 
|  |  | 
|  | explicit local_string (gdb::unique_xmalloc_ptr<char> str) | 
|  | : contents (std::move (str)), | 
|  | len (strlen (contents.get ())) | 
|  | { } | 
|  |  | 
|  | const char *get () const | 
|  | { return contents.get (); } | 
|  |  | 
|  | std::string_view as_view () const | 
|  | { return std::string_view (contents.get (), len); } | 
|  |  | 
|  | /* \0-terminated string contents.  */ | 
|  | gdb::unique_xmalloc_ptr<char> contents; | 
|  | /* Length of the string.  */ | 
|  | size_t len; | 
|  | }; | 
|  |  | 
|  | /* Equality object for the set.  */ | 
|  | struct str_eq | 
|  | { | 
|  | using is_transparent = void; | 
|  |  | 
|  | bool operator() (std::string_view lhs, const local_string &rhs) | 
|  | const noexcept | 
|  | { | 
|  | return lhs == rhs.as_view (); | 
|  | } | 
|  |  | 
|  | bool operator() (const local_string &lhs, const local_string &rhs) | 
|  | const noexcept | 
|  | { | 
|  | return (*this) (lhs.as_view (), rhs); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /* Hash object for the set.  */ | 
|  | struct str_hash | 
|  | { | 
|  | using is_transparent = void; | 
|  | using is_avalanching = void; | 
|  |  | 
|  | uint64_t operator() (const local_string &rhs) const noexcept | 
|  | { | 
|  | return (*this) (rhs.as_view ()); | 
|  | } | 
|  |  | 
|  | uint64_t operator() (std::string_view rhs) const noexcept | 
|  | { | 
|  | return ankerl::unordered_dense::hash<std::string_view> () (rhs); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /* The strings.  */ | 
|  | gdb::unordered_set<local_string, str_hash, str_eq> m_set; | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | #endif /* GDBSUPPORT_STRING_SET_H */ |