// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_TINT_UTILS_ENUM_SET_H_
#define SRC_TINT_UTILS_ENUM_SET_H_

#include <cstdint>
#include <functional>
#include <ostream>
#include <type_traits>
#include <utility>

namespace tint {
namespace utils {

/// EnumSet is a set of enum values.
/// @note As the EnumSet is backed by a single uint64_t value, it can only hold
/// enum values in the range [0 .. 63].
template <typename ENUM>
struct EnumSet {
 public:
  /// Enum is the enum type this EnumSet wraps
  using Enum = ENUM;

  /// Constructor. Initializes the EnumSet with zero.
  constexpr EnumSet() = default;

  /// Copy constructor.
  /// @param s the set to copy
  constexpr EnumSet(const EnumSet& s) = default;

  /// Constructor. Initializes the EnumSet with the given values.
  /// @param values the enumerator values to construct the set with
  template <typename... VALUES>
  explicit constexpr EnumSet(VALUES... values) : set(Union(values...)) {}

  /// Copy assignment operator.
  /// @param set the set to assign to this set
  /// @return this set so calls can be chained
  inline EnumSet& operator=(const EnumSet& set) = default;

  /// Copy assignment operator.
  /// @param e the enum value
  /// @return this set so calls can be chained
  inline EnumSet& operator=(Enum e) { return *this = EnumSet{e}; }

  /// Adds all the given values to this set
  /// @param values the values to add
  /// @return this set so calls can be chained
  template <typename... VALUES>
  inline EnumSet& Add(VALUES... values) {
    return Add(EnumSet(std::forward<VALUES>(values)...));
  }

  /// Removes all the given values from this set
  /// @param values the values to remove
  /// @return this set so calls can be chained
  template <typename... VALUES>
  inline EnumSet& Remove(VALUES... values) {
    return Remove(EnumSet(std::forward<VALUES>(values)...));
  }

  /// Adds all of s to this set
  /// @param s the enum value
  /// @return this set so calls can be chained
  inline EnumSet& Add(EnumSet s) { return (*this = *this + s); }

  /// Removes all of s from this set
  /// @param s the enum value
  /// @return this set so calls can be chained
  inline EnumSet& Remove(EnumSet s) { return (*this = *this - s); }

  /// @param e the enum value
  /// @returns a copy of this set with e added
  inline EnumSet operator+(Enum e) const {
    EnumSet out;
    out.set = set | Bit(e);
    return out;
  }

  /// @param e the enum value
  /// @returns a copy of this set with e removed
  inline EnumSet operator-(Enum e) const {
    EnumSet out;
    out.set = set & ~Bit(e);
    return out;
  }

  /// @param s the other set
  /// @returns the union of this set with s (this ∪ rhs)
  inline EnumSet operator+(EnumSet s) const {
    EnumSet out;
    out.set = set | s.set;
    return out;
  }

  /// @param s the other set
  /// @returns the set of entries found in this but not in s (this \ s)
  inline EnumSet operator-(EnumSet s) const {
    EnumSet out;
    out.set = set & ~s.set;
    return out;
  }

  /// @param s the other set
  /// @returns the intersection of this set with s (this ∩ rhs)
  inline EnumSet operator&(EnumSet s) const {
    EnumSet out;
    out.set = set & s.set;
    return out;
  }

  /// @param e the enum value
  /// @return true if the set contains `e`
  inline bool Contains(Enum e) const { return (set & Bit(e)) != 0; }

  /// @return true if the set is empty
  inline bool Empty() const { return set == 0; }

  /// Equality operator
  /// @param rhs the other EnumSet to compare this to
  /// @return true if this EnumSet is equal to rhs
  inline bool operator==(EnumSet rhs) const { return set == rhs.set; }

  /// Inequality operator
  /// @param rhs the other EnumSet to compare this to
  /// @return true if this EnumSet is not equal to rhs
  inline bool operator!=(EnumSet rhs) const { return set != rhs.set; }

  /// Equality operator
  /// @param rhs the enum to compare this to
  /// @return true if this EnumSet only contains `rhs`
  inline bool operator==(Enum rhs) const { return set == Bit(rhs); }

  /// Inequality operator
  /// @param rhs the enum to compare this to
  /// @return false if this EnumSet only contains `rhs`
  inline bool operator!=(Enum rhs) const { return set != Bit(rhs); }

  /// @return the underlying value for the EnumSet
  inline uint64_t Value() const { return set; }

  /// Iterator provides read-only, unidirectional iterator over the enums of an
  /// EnumSet.
  class Iterator {
    static constexpr int8_t kEnd = 63;

    Iterator(uint64_t s, int8_t b) : set(s), pos(b) {}

    /// Make the constructor accessible to the EnumSet.
    friend struct EnumSet;

   public:
    /// @return the Enum value at this point in the iterator
    Enum operator*() const { return static_cast<Enum>(pos); }

    /// Increments the iterator
    /// @returns this iterator
    Iterator& operator++() {
      while (pos < kEnd) {
        pos++;
        if (set & (static_cast<uint64_t>(1) << static_cast<uint64_t>(pos))) {
          break;
        }
      }
      return *this;
    }

    /// Equality operator
    /// @param rhs the Iterator to compare this to
    /// @return true if the two iterators are equal
    bool operator==(const Iterator& rhs) const {
      return set == rhs.set && pos == rhs.pos;
    }

    /// Inequality operator
    /// @param rhs the Iterator to compare this to
    /// @return true if the two iterators are different
    bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }

   private:
    const uint64_t set;
    int8_t pos;
  };

  /// @returns an read-only iterator to the beginning of the set
  Iterator begin() {
    auto it = Iterator{set, -1};
    ++it;  // Move to first set bit
    return it;
  }

  /// @returns an iterator to the beginning of the set
  Iterator end() { return Iterator{set, Iterator::kEnd}; }

 private:
  static constexpr uint64_t Bit(Enum value) {
    return static_cast<uint64_t>(1) << static_cast<uint64_t>(value);
  }

  static constexpr uint64_t Union() { return 0; }

  template <typename FIRST, typename... VALUES>
  static constexpr uint64_t Union(FIRST first, VALUES... values) {
    return Bit(first) | Union(values...);
  }

  uint64_t set = 0;
};

/// Writes the EnumSet to the std::ostream.
/// @param out the std::ostream to write to
/// @param set the EnumSet to write
/// @returns out so calls can be chained
template <typename ENUM>
inline std::ostream& operator<<(std::ostream& out, EnumSet<ENUM> set) {
  out << "{";
  bool first = true;
  for (auto e : set) {
    if (!first) {
      out << ", ";
    }
    first = false;
    out << e;
  }
  return out << "}";
}

}  // namespace utils
}  // namespace tint

namespace std {

/// Custom std::hash specialization for tint::utils::EnumSet<T>
template <typename T>
class hash<tint::utils::EnumSet<T>> {
 public:
  /// @param e the EnumSet to create a hash for
  /// @return the hash value
  inline std::size_t operator()(const tint::utils::EnumSet<T>& e) const {
    return std::hash<uint64_t>()(e.Value());
  }
};

}  // namespace std

#endif  // SRC_TINT_UTILS_ENUM_SET_H_
