/* Copyright (C) 2022-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_PACKED_H
#define GDBSUPPORT_PACKED_H

#include "traits.h"
#include <atomic>

/* Each instantiation and full specialization of the packed template
   defines a type that behaves like a given scalar type, but that has
   byte alignment, and, may optionally have a smaller size than the
   given scalar type.  This is typically used as alternative to
   bit-fields (and ENUM_BITFIELD), when the fields must have separate
   memory locations to avoid data races.  */

/* There are two implementations here -- one standard compliant, using
   a byte array for internal representation, and another that relies
   on bitfields and attribute packed (and attribute gcc_struct on
   Windows).  The latter is preferable, as it is more convenient when
   debugging GDB -- printing a struct packed variable prints its field
   using its natural type, which is particularly useful if the type is
   an enum -- but may not work on all compilers.  */

/* Clang targeting Windows does not support attribute gcc_struct, so
   we use the alternative byte array implementation there. */
#if defined _WIN32 && defined __clang__
# define PACKED_USE_ARRAY 1
#else
# define PACKED_USE_ARRAY 0
#endif

/* For the preferred implementation, we need gcc_struct on Windows, as
   otherwise the size of e.g., "packed<int, 1>" will be larger than
   what we want.  Clang targeting Windows does not support attribute
   gcc_struct.  */
#if !PACKED_USE_ARRAY && defined _WIN32 && !defined __clang__
# define ATTRIBUTE_GCC_STRUCT __attribute__((__gcc_struct__))
#else
# define ATTRIBUTE_GCC_STRUCT
#endif

template<typename T, size_t Bytes = sizeof (T)>
struct ATTRIBUTE_GCC_STRUCT packed
{
public:
  packed () noexcept = default;

  packed (T val)
  {
    static_assert (sizeof (ULONGEST) >= sizeof (T));

#if PACKED_USE_ARRAY
    ULONGEST tmp = val;
    for (int i = (Bytes - 1); i >= 0; --i)
      {
	m_bytes[i] = (gdb_byte) tmp;
	tmp >>= HOST_CHAR_BIT;
      }
#else
    m_val = val;
#endif

    /* Ensure size and alignment are what we expect.  */
    static_assert (sizeof (packed) == Bytes);
    static_assert (alignof (packed) == 1);

    /* Make sure packed can be wrapped with std::atomic.  */
    static_assert (std::is_trivially_copyable<packed>::value);
    static_assert (std::is_copy_constructible<packed>::value);
    static_assert (std::is_move_constructible<packed>::value);
    static_assert (std::is_copy_assignable<packed>::value);
    static_assert (std::is_move_assignable<packed>::value);
  }

  operator T () const noexcept
  {
#if PACKED_USE_ARRAY
    ULONGEST tmp = 0;
    for (int i = 0;;)
      {
	tmp |= m_bytes[i];
	if (++i == Bytes)
	  break;
	tmp <<= HOST_CHAR_BIT;
      }
    return (T) tmp;
#else
    return m_val;
#endif
  }

private:
#if PACKED_USE_ARRAY
  gdb_byte m_bytes[Bytes];
#else
  T m_val : (Bytes * HOST_CHAR_BIT) ATTRIBUTE_PACKED;
#endif
};

/* Add some comparisons between std::atomic<packed<T>> and packed<T>
   and T.  We need this because even though std::atomic<T> doesn't
   define these operators, the relational expressions still work via
   implicit conversions.  Those wouldn't work when wrapped in packed
   without these operators, because they'd require two implicit
   conversions to go from T to packed<T> to std::atomic<packed<T>>
   (and back), and C++ only does one.  */

#define PACKED_ATOMIC_OP(OP)						\
  template<typename T, size_t Bytes>					\
  bool operator OP (const std::atomic<packed<T, Bytes>> &lhs,		\
		    const std::atomic<packed<T, Bytes>> &rhs)		\
  {									\
    return lhs.load () OP rhs.load ();					\
  }									\
									\
  template<typename T, size_t Bytes>					\
  bool operator OP (T lhs, const std::atomic<packed<T, Bytes>> &rhs)	\
  {									\
    return lhs OP rhs.load ();						\
  }									\
									\
  template<typename T, size_t Bytes>					\
  bool operator OP (const std::atomic<packed<T, Bytes>> &lhs, T rhs)	\
  {									\
    return lhs.load () OP rhs;						\
  }									\
									\
  template<typename T, size_t Bytes>					\
  bool operator OP (const std::atomic<packed<T, Bytes>> &lhs,		\
		    packed<T, Bytes> rhs)				\
  {									\
    return lhs.load () OP rhs;						\
  }									\
									\
  template<typename T, size_t Bytes>					\
  bool operator OP (packed<T, Bytes> lhs,				\
		    const std::atomic<packed<T, Bytes>> &rhs)		\
  {									\
    return lhs OP rhs.load ();						\
  }

PACKED_ATOMIC_OP (==)
PACKED_ATOMIC_OP (!=)
PACKED_ATOMIC_OP (>)
PACKED_ATOMIC_OP (<)
PACKED_ATOMIC_OP (>=)
PACKED_ATOMIC_OP (<=)

#undef PACKED_ATOMIC_OP

#endif /* GDBSUPPORT_PACKED_H */
