/* Copyright (C) 2022-2024 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 PACKED_H
#define 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 aligment 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
