// Copyright 2020 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_CASTABLE_H_
#define SRC_CASTABLE_H_

#include <cstdint>
#include <type_traits>
#include <utility>

namespace tint {

/// Helper macro to instantiate the ClassID for `CLASS`.
#define TINT_INSTANTIATE_CLASS_ID(CLASS) \
  template <>                            \
  const char ::tint::ClassID::Unique<CLASS>::token = 0

/// ClassID represents a unique, comparable identifier for a C++ type.
class ClassID {
 private:
  /// Helper template that holds a single static field, which is used by Of()
  /// to obtain a unique identifier by taking the field's address.
  template <typename T>
  struct Unique {
    static const char token;
  };

 public:
  /// @returns the unique ClassID for the type T.
  template <typename T>
  static ClassID Of() {
    // Take the address of a static variable to produce a unique identifier for
    // the type T.
    return ClassID{reinterpret_cast<uintptr_t>(&Unique<T>::token)};
  }

  /// Equality operator
  /// @param rhs the ClassID to compare against
  /// @returns true if this ClassID is equal to `rhs`
  inline bool operator==(ClassID& rhs) const { return id == rhs.id; }

 private:
  inline explicit ClassID(uintptr_t v) : id(v) {}

  const uintptr_t id;
};

/// CastableBase is the base class for all Castable objects.
/// It is not encouraged to directly derive from CastableBase without using the
/// Castable helper template.
/// @see Castable
class CastableBase {
 public:
  /// Move constructor
  CastableBase(CastableBase&&) = default;

  virtual ~CastableBase() = default;

  /// @returns true if this object is of, or derives from a class with the
  /// ClassID `id`.
  /// @param id the ClassID to test for
  virtual bool Is(ClassID id) const;

  /// @returns true if this object is of, or derives from the class `TO`
  template <typename TO>
  bool Is() const {
    using FROM = CastableBase;
    constexpr const bool downcast = std::is_base_of<FROM, TO>::value;
    constexpr const bool upcast = std::is_base_of<TO, FROM>::value;
    constexpr const bool nocast = std::is_same<FROM, TO>::value;
    static_assert(upcast || downcast || nocast, "impossible cast");

    if (upcast || nocast) {
      return true;
    }

    return Is(ClassID::Of<TO>());
  }

  /// @returns this object dynamically cast to the type `TO` or `nullptr` if
  /// this object does not derive from `TO`.
  template <typename TO>
  inline TO* As() {
    return Is<TO>() ? static_cast<TO*>(this) : nullptr;
  }

  /// @returns this object dynamically cast to the type `TO` or `nullptr` if
  /// this object does not derive from `TO`.
  template <typename TO>
  inline const TO* As() const {
    return Is<TO>() ? static_cast<const TO*>(this) : nullptr;
  }

 protected:
  CastableBase() = default;
};

/// Castable is a helper to derive `CLASS` from `BASE`, automatically
/// implementing the Is() and As() methods, along with a #Base type alias.
///
/// Example usage:
///
/// ```
/// class Animal : public Castable<Animal> {};
///
/// class Sheep : public Castable<Sheep, Animal> {};
///
/// Sheep* cast_to_sheep(Animal* animal) {
///    // You can query whether a Castable is of the given type with Is<T>():
///    printf("animal is a sheep? %s", animal->Is<Sheep>() ? "yes" : "no");
///
///    // You can always just try the cast with As<T>().
///    // If the object is not of the correct type, As<T>() will return nullptr:
///    return animal->As<Sheep>();
/// }
/// ```
template <typename CLASS, typename BASE = CastableBase>
class Castable : public BASE {
 public:
  // Inherit the `BASE` class constructors.
  using BASE::BASE;

  /// A type alias for `CLASS` to easily access the `BASE` class members.
  /// Base actually aliases to the Castable instead of `BASE` so that you can
  /// use Base in the `CLASS` constructor.
  using Base = Castable;

  /// @returns true if this object is of, or derives from a class with the
  /// ClassID `id`.
  /// @param id the ClassID to test for
  bool Is(ClassID id) const override {
    return ClassID::Of<CLASS>() == id || BASE::Is(id);
  }

  /// @returns true if this object is of, or derives from the class `TO`
  template <typename TO>
  bool Is() const {
    using FROM = Castable;
    constexpr const bool downcast = std::is_base_of<FROM, TO>::value;
    constexpr const bool upcast = std::is_base_of<TO, FROM>::value;
    constexpr const bool nocast = std::is_same<FROM, TO>::value;
    static_assert(upcast || downcast || nocast, "impossible cast");

    if (upcast || nocast) {
      return true;
    }

    return Is(ClassID::Of<TO>());
  }

  /// @returns this object dynamically cast to the type `TO` or `nullptr` if
  /// this object does not derive from `TO`.
  template <typename TO>
  inline TO* As() {
    return Is<TO>() ? static_cast<TO*>(this) : nullptr;
  }

  /// @returns this object dynamically cast to the type `TO` or `nullptr` if
  /// this object does not derive from `TO`.
  template <typename TO>
  inline const TO* As() const {
    return Is<TO>() ? static_cast<const TO*>(this) : nullptr;
  }
};

/// As() dynamically casts `obj` to the target type `TO`.
/// @returns the cast object, or nullptr if `obj` is `nullptr` or not of the
/// type `TO`.
/// @param obj the object to cast
template <typename TO, typename FROM>
inline TO* As(FROM* obj) {
  if (obj == nullptr) {
    return nullptr;
  }
  return obj->template As<TO>();
}

}  // namespace tint

#endif  // SRC_CASTABLE_H_
