//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the CharUnits class
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_CHARUNITS_H
#define LLVM_CLANG_AST_CHARUNITS_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"

namespace clang {

  /// CharUnits - This is an opaque type for sizes expressed in character units.
  /// Instances of this type represent a quantity as a multiple of the size
  /// of the standard C type, char, on the target architecture. As an opaque
  /// type, CharUnits protects you from accidentally combining operations on
  /// quantities in bit units and character units.
  ///
  /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
  /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
  /// the same quantity of storage. However, we use the term 'character unit'
  /// rather than 'byte' to avoid an implication that a character unit is
  /// exactly 8 bits.
  ///
  /// For portability, never assume that a target character is 8 bits wide. Use
  /// CharUnit values wherever you calculate sizes, offsets, or alignments
  /// in character units.
  class CharUnits {
    public:
      typedef int64_t QuantityType;

    private:
      QuantityType Quantity = 0;

      explicit CharUnits(QuantityType C) : Quantity(C) {}

    public:

      /// CharUnits - A default constructor.
      CharUnits() = default;

      /// Zero - Construct a CharUnits quantity of zero.
      static CharUnits Zero() {
        return CharUnits(0);
      }

      /// One - Construct a CharUnits quantity of one.
      static CharUnits One() {
        return CharUnits(1);
      }

      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
      static CharUnits fromQuantity(QuantityType Quantity) {
        return CharUnits(Quantity);
      }

      // Compound assignment.
      CharUnits& operator+= (const CharUnits &Other) {
        Quantity += Other.Quantity;
        return *this;
      }
      CharUnits& operator++ () {
        ++Quantity;
        return *this;
      }
      CharUnits operator++ (int) {
        return CharUnits(Quantity++);
      }
      CharUnits& operator-= (const CharUnits &Other) {
        Quantity -= Other.Quantity;
        return *this;
      }
      CharUnits& operator-- () {
        --Quantity;
        return *this;
      }
      CharUnits operator-- (int) {
        return CharUnits(Quantity--);
      }

      // Comparison operators.
      bool operator== (const CharUnits &Other) const {
        return Quantity == Other.Quantity;
      }
      bool operator!= (const CharUnits &Other) const {
        return Quantity != Other.Quantity;
      }

      // Relational operators.
      bool operator<  (const CharUnits &Other) const {
        return Quantity <  Other.Quantity;
      }
      bool operator<= (const CharUnits &Other) const {
        return Quantity <= Other.Quantity;
      }
      bool operator>  (const CharUnits &Other) const {
        return Quantity >  Other.Quantity;
      }
      bool operator>= (const CharUnits &Other) const {
        return Quantity >= Other.Quantity;
      }

      // Other predicates.

      /// isZero - Test whether the quantity equals zero.
      bool isZero() const     { return Quantity == 0; }

      /// isOne - Test whether the quantity equals one.
      bool isOne() const      { return Quantity == 1; }

      /// isPositive - Test whether the quantity is greater than zero.
      bool isPositive() const { return Quantity  > 0; }

      /// isNegative - Test whether the quantity is less than zero.
      bool isNegative() const { return Quantity  < 0; }

      /// isPowerOfTwo - Test whether the quantity is a power of two.
      /// Zero is not a power of two.
      bool isPowerOfTwo() const {
        return (Quantity & -Quantity) == Quantity;
      }

      /// Test whether this is a multiple of the other value.
      ///
      /// Among other things, this promises that
      /// self.alignTo(N) will just return self.
      bool isMultipleOf(CharUnits N) const {
        return (*this % N) == 0;
      }

      // Arithmetic operators.
      CharUnits operator* (QuantityType N) const {
        return CharUnits(Quantity * N);
      }
      CharUnits &operator*= (QuantityType N) {
        Quantity *= N;
        return *this;
      }
      CharUnits operator/ (QuantityType N) const {
        return CharUnits(Quantity / N);
      }
      CharUnits &operator/= (QuantityType N) {
        Quantity /= N;
        return *this;
      }
      QuantityType operator/ (const CharUnits &Other) const {
        return Quantity / Other.Quantity;
      }
      CharUnits operator% (QuantityType N) const {
        return CharUnits(Quantity % N);
      }
      QuantityType operator% (const CharUnits &Other) const {
        return Quantity % Other.Quantity;
      }
      CharUnits operator+ (const CharUnits &Other) const {
        return CharUnits(Quantity + Other.Quantity);
      }
      CharUnits operator- (const CharUnits &Other) const {
        return CharUnits(Quantity - Other.Quantity);
      }
      CharUnits operator- () const {
        return CharUnits(-Quantity);
      }


      // Conversions.

      /// getQuantity - Get the raw integer representation of this quantity.
      QuantityType getQuantity() const { return Quantity; }

      /// alignTo - Returns the next integer (mod 2**64) that is
      /// greater than or equal to this quantity and is a multiple of \p Align.
      /// Align must be non-zero.
      CharUnits alignTo(const CharUnits &Align) const {
        return CharUnits(llvm::alignTo(Quantity, Align.Quantity));
      }

      /// Given that this is a non-zero alignment value, what is the
      /// alignment at the given offset?
      CharUnits alignmentAtOffset(CharUnits offset) const {
        assert(Quantity != 0 && "offsetting from unknown alignment?");
        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
      }

      /// Given that this is the alignment of the first element of an
      /// array, return the minimum alignment of any element in the array.
      CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
        // Since we don't track offsetted alignments, the alignment of
        // the second element (or any odd element) will be minimally
        // aligned.
        return alignmentAtOffset(elementSize);
      }


  }; // class CharUnit
} // namespace clang

inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
                                   const clang::CharUnits &CU) {
  return CU * Scale;
}

namespace llvm {

template<> struct DenseMapInfo<clang::CharUnits> {
  static clang::CharUnits getEmptyKey() {
    clang::CharUnits::QuantityType Quantity =
      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();

    return clang::CharUnits::fromQuantity(Quantity);
  }

  static clang::CharUnits getTombstoneKey() {
    clang::CharUnits::QuantityType Quantity =
      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();

    return clang::CharUnits::fromQuantity(Quantity);
  }

  static unsigned getHashValue(const clang::CharUnits &CU) {
    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
  }

  static bool isEqual(const clang::CharUnits &LHS,
                      const clang::CharUnits &RHS) {
    return LHS == RHS;
  }
};

} // end namespace llvm

#endif // LLVM_CLANG_AST_CHARUNITS_H
