// Copyright 2020 The Dawn 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 COMMON_TYPEDINTEGER_H_
#define COMMON_TYPEDINTEGER_H_

#include "dawn/common/Assert.h"
#include "dawn/common/UnderlyingType.h"

#include <limits>
#include <type_traits>

// TypedInteger is helper class that provides additional type safety in Debug.
//  - Integers of different (Tag, BaseIntegerType) may not be used interoperably
//  - Allows casts only to the underlying type.
//  - Integers of the same (Tag, BaseIntegerType) may be compared or assigned.
// This class helps ensure that the many types of indices in Dawn aren't mixed up and used
// interchangably.
// In Release builds, when DAWN_ENABLE_ASSERTS is not defined, TypedInteger is a passthrough
// typedef of the underlying type.
//
// Example:
//     using UintA = TypedInteger<struct TypeA, uint32_t>;
//     using UintB = TypedInteger<struct TypeB, uint32_t>;
//
//  in Release:
//     using UintA = uint32_t;
//     using UintB = uint32_t;
//
//  in Debug:
//     using UintA = detail::TypedIntegerImpl<struct TypeA, uint32_t>;
//     using UintB = detail::TypedIntegerImpl<struct TypeB, uint32_t>;
//
//     Assignment, construction, comparison, and arithmetic with TypedIntegerImpl are allowed
//     only for typed integers of exactly the same type. Further, they must be
//     created / cast explicitly; there is no implicit conversion.
//
//     UintA a(2);
//     uint32_t aValue = static_cast<uint32_t>(a);
//
namespace detail {
    template <typename Tag, typename T>
    class TypedIntegerImpl;
}  // namespace detail

template <typename Tag, typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
#if defined(DAWN_ENABLE_ASSERTS)
using TypedInteger = detail::TypedIntegerImpl<Tag, T>;
#else
using TypedInteger = T;
#endif

namespace detail {
    template <typename Tag, typename T>
    class alignas(T) TypedIntegerImpl {
        static_assert(std::is_integral<T>::value, "TypedInteger must be integral");
        T mValue;

      public:
        constexpr TypedIntegerImpl() : mValue(0) {
            static_assert(alignof(TypedIntegerImpl) == alignof(T));
            static_assert(sizeof(TypedIntegerImpl) == sizeof(T));
        }

        // Construction from non-narrowing integral types.
        template <typename I,
                  typename = std::enable_if_t<
                      std::is_integral<I>::value &&
                      std::numeric_limits<I>::max() <= std::numeric_limits<T>::max() &&
                      std::numeric_limits<I>::min() >= std::numeric_limits<T>::min()>>
        explicit constexpr TypedIntegerImpl(I rhs) : mValue(static_cast<T>(rhs)) {
        }

        // Allow explicit casts only to the underlying type. If you're casting out of an
        // TypedInteger, you should know what what you're doing, and exactly what type you
        // expect.
        explicit constexpr operator T() const {
            return static_cast<T>(this->mValue);
        }

// Same-tag TypedInteger comparison operators
#define TYPED_COMPARISON(op)                                        \
    constexpr bool operator op(const TypedIntegerImpl& rhs) const { \
        return mValue op rhs.mValue;                                \
    }
        TYPED_COMPARISON(<)
        TYPED_COMPARISON(<=)
        TYPED_COMPARISON(>)
        TYPED_COMPARISON(>=)
        TYPED_COMPARISON(==)
        TYPED_COMPARISON(!=)
#undef TYPED_COMPARISON

        // Increment / decrement operators for for-loop iteration
        constexpr TypedIntegerImpl& operator++() {
            ASSERT(this->mValue < std::numeric_limits<T>::max());
            ++this->mValue;
            return *this;
        }

        constexpr TypedIntegerImpl operator++(int) {
            TypedIntegerImpl ret = *this;

            ASSERT(this->mValue < std::numeric_limits<T>::max());
            ++this->mValue;
            return ret;
        }

        constexpr TypedIntegerImpl& operator--() {
            assert(this->mValue > std::numeric_limits<T>::min());
            --this->mValue;
            return *this;
        }

        constexpr TypedIntegerImpl operator--(int) {
            TypedIntegerImpl ret = *this;

            ASSERT(this->mValue > std::numeric_limits<T>::min());
            --this->mValue;
            return ret;
        }

        template <typename T2 = T>
        static constexpr std::enable_if_t<std::is_unsigned<T2>::value, decltype(T(0) + T2(0))>
        AddImpl(TypedIntegerImpl<Tag, T> lhs, TypedIntegerImpl<Tag, T2> rhs) {
            static_assert(std::is_same<T, T2>::value);

            // Overflow would wrap around
            ASSERT(lhs.mValue + rhs.mValue >= lhs.mValue);
            return lhs.mValue + rhs.mValue;
        }

        template <typename T2 = T>
        static constexpr std::enable_if_t<std::is_signed<T2>::value, decltype(T(0) + T2(0))>
        AddImpl(TypedIntegerImpl<Tag, T> lhs, TypedIntegerImpl<Tag, T2> rhs) {
            static_assert(std::is_same<T, T2>::value);

            if (lhs.mValue > 0) {
                // rhs is positive: |rhs| is at most the distance between max and |lhs|.
                // rhs is negative: (positive + negative) won't overflow
                ASSERT(rhs.mValue <= std::numeric_limits<T>::max() - lhs.mValue);
            } else {
                // rhs is postive: (negative + positive) won't underflow
                // rhs is negative: |rhs| isn't less than the (negative) distance between min
                // and |lhs|
                ASSERT(rhs.mValue >= std::numeric_limits<T>::min() - lhs.mValue);
            }
            return lhs.mValue + rhs.mValue;
        }

        template <typename T2 = T>
        static constexpr std::enable_if_t<std::is_unsigned<T>::value, decltype(T(0) - T2(0))>
        SubImpl(TypedIntegerImpl<Tag, T> lhs, TypedIntegerImpl<Tag, T2> rhs) {
            static_assert(std::is_same<T, T2>::value);

            // Overflow would wrap around
            ASSERT(lhs.mValue - rhs.mValue <= lhs.mValue);
            return lhs.mValue - rhs.mValue;
        }

        template <typename T2 = T>
        static constexpr std::enable_if_t<std::is_signed<T>::value, decltype(T(0) - T2(0))> SubImpl(
            TypedIntegerImpl<Tag, T> lhs,
            TypedIntegerImpl<Tag, T2> rhs) {
            static_assert(std::is_same<T, T2>::value);

            if (lhs.mValue > 0) {
                // rhs is positive: positive minus positive won't overflow
                // rhs is negative: |rhs| isn't less than the (negative) distance between |lhs|
                // and max.
                ASSERT(rhs.mValue >= lhs.mValue - std::numeric_limits<T>::max());
            } else {
                // rhs is positive: |rhs| is at most the distance between min and |lhs|
                // rhs is negative: negative minus negative won't overflow
                ASSERT(rhs.mValue <= lhs.mValue - std::numeric_limits<T>::min());
            }
            return lhs.mValue - rhs.mValue;
        }

        template <typename T2 = T>
        constexpr std::enable_if_t<std::is_signed<T2>::value, TypedIntegerImpl> operator-() const {
            static_assert(std::is_same<T, T2>::value);
            // The negation of the most negative value cannot be represented.
            ASSERT(this->mValue != std::numeric_limits<T>::min());
            return TypedIntegerImpl(-this->mValue);
        }

        constexpr TypedIntegerImpl operator+(TypedIntegerImpl rhs) const {
            auto result = AddImpl(*this, rhs);
            static_assert(std::is_same<T, decltype(result)>::value, "Use ityp::Add instead.");
            return TypedIntegerImpl(result);
        }

        constexpr TypedIntegerImpl operator-(TypedIntegerImpl rhs) const {
            auto result = SubImpl(*this, rhs);
            static_assert(std::is_same<T, decltype(result)>::value, "Use ityp::Sub instead.");
            return TypedIntegerImpl(result);
        }
    };

}  // namespace detail

namespace std {

    template <typename Tag, typename T>
    class numeric_limits<detail::TypedIntegerImpl<Tag, T>> : public numeric_limits<T> {
      public:
        static detail::TypedIntegerImpl<Tag, T> max() noexcept {
            return detail::TypedIntegerImpl<Tag, T>(std::numeric_limits<T>::max());
        }
        static detail::TypedIntegerImpl<Tag, T> min() noexcept {
            return detail::TypedIntegerImpl<Tag, T>(std::numeric_limits<T>::min());
        }
    };

}  // namespace std

namespace ityp {

    // These helpers below are provided since the default arithmetic operators for small integer
    // types like uint8_t and uint16_t return integers, not their same type. To avoid lots of
    // casting or conditional code between Release/Debug. Callsites should use ityp::Add(a, b) and
    // ityp::Sub(a, b) instead.

    template <typename Tag, typename T>
    constexpr ::detail::TypedIntegerImpl<Tag, T> Add(::detail::TypedIntegerImpl<Tag, T> lhs,
                                                     ::detail::TypedIntegerImpl<Tag, T> rhs) {
        return ::detail::TypedIntegerImpl<Tag, T>(
            static_cast<T>(::detail::TypedIntegerImpl<Tag, T>::AddImpl(lhs, rhs)));
    }

    template <typename Tag, typename T>
    constexpr ::detail::TypedIntegerImpl<Tag, T> Sub(::detail::TypedIntegerImpl<Tag, T> lhs,
                                                     ::detail::TypedIntegerImpl<Tag, T> rhs) {
        return ::detail::TypedIntegerImpl<Tag, T>(
            static_cast<T>(::detail::TypedIntegerImpl<Tag, T>::SubImpl(lhs, rhs)));
    }

    template <typename T>
    constexpr std::enable_if_t<std::is_integral<T>::value, T> Add(T lhs, T rhs) {
        return static_cast<T>(lhs + rhs);
    }

    template <typename T>
    constexpr std::enable_if_t<std::is_integral<T>::value, T> Sub(T lhs, T rhs) {
        return static_cast<T>(lhs - rhs);
    }

}  // namespace ityp

#endif  // COMMON_TYPEDINTEGER_H_
