// 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_UTILS_ENUM_SET_H_
#define SRC_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_UTILS_ENUM_SET_H_
