/* String-interning set

   Copyright (C) 2025-2026 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 */
