/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Implements a smart pointer asserted to remain within a range specified at
 * construction.
 */

#ifndef mozilla_RangedPtr_h_
#define mozilla_RangedPtr_h_

#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/Util.h"

namespace mozilla {

/*
 * RangedPtr is a smart pointer restricted to an address range specified at
 * creation.  The pointer (and any smart pointers derived from it) must remain
 * within the range [start, end] (inclusive of end to facilitate use as
 * sentinels).  Dereferencing or indexing into the pointer (or pointers derived
 * from it) must remain within the range [start, end).  All the standard pointer
 * operators are defined on it; in debug builds these operations assert that the
 * range specified at construction is respected.
 *
 * In theory passing a smart pointer instance as an argument can be slightly
 * slower than passing a T* (due to ABI requirements for passing structs versus
 * passing pointers), if the method being called isn't inlined.  If you are in
 * extremely performance-critical code, you may want to be careful using this
 * smart pointer as an argument type.
 *
 * RangedPtr<T> intentionally does not implicitly convert to T*.  Use get() to
 * explicitly convert to T*.  Keep in mind that the raw pointer of course won't
 * implement bounds checking in debug builds.
 */
template<typename T>
class RangedPtr
{
    T* ptr;

#ifdef DEBUG
    T* const rangeStart;
    T* const rangeEnd;
#endif

    typedef void (RangedPtr::* ConvertibleToBool)();
    void nonNull() {}

    void checkSanity() {
      MOZ_ASSERT(rangeStart <= ptr);
      MOZ_ASSERT(ptr <= rangeEnd);
    }

    /* Creates a new pointer for |p|, restricted to this pointer's range. */
    RangedPtr<T> create(T *p) const {
#ifdef DEBUG
      return RangedPtr<T>(p, rangeStart, rangeEnd);
#else
      return RangedPtr<T>(p, NULL, size_t(0));
#endif
    }

    uintptr_t asUintptr() const { return uintptr_t(ptr); }

  public:
    RangedPtr(T* p, T* start, T* end)
      : ptr(p)
#ifdef DEBUG
      , rangeStart(start), rangeEnd(end)
#endif
    {
      MOZ_ASSERT(rangeStart <= rangeEnd);
      checkSanity();
    }
    RangedPtr(T* p, T* start, size_t length)
      : ptr(p)
#ifdef DEBUG
      , rangeStart(start), rangeEnd(start + length)
#endif
    {
      MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
      MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
      checkSanity();
    }

    /* Equivalent to RangedPtr(p, p, length). */
    RangedPtr(T* p, size_t length)
      : ptr(p)
#ifdef DEBUG
      , rangeStart(p), rangeEnd(p + length)
#endif
    {
      MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
      MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
      checkSanity();
    }

    /* Equivalent to RangedPtr(arr, arr, N). */
    template<size_t N>
    RangedPtr(T (&arr)[N])
      : ptr(arr)
#ifdef DEBUG
      , rangeStart(arr), rangeEnd(arr + N)
#endif
    {
      checkSanity();
    }

    T* get() const {
      return ptr;
    }

    operator ConvertibleToBool() const { return ptr ? &RangedPtr::nonNull : 0; }

    /*
     * You can only assign one RangedPtr into another if the two pointers have
     * the same valid range:
     *
     *   char arr1[] = "hi";
     *   char arr2[] = "bye";
     *   RangedPtr<char> p1(arr1, 2);
     *   p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
     *   p1 = RangedPtr<char>(arr2, 3);                  // asserts
     */
    RangedPtr<T>& operator=(const RangedPtr<T>& other) {
      MOZ_ASSERT(rangeStart == other.rangeStart);
      MOZ_ASSERT(rangeEnd == other.rangeEnd);
      ptr = other.ptr;
      checkSanity();
      return *this;
    }

    RangedPtr<T> operator+(size_t inc) {
      MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
      MOZ_ASSERT(asUintptr() + inc * sizeof(T) >= asUintptr());
      return create(ptr + inc);
    }

    RangedPtr<T> operator-(size_t dec) {
      MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
      MOZ_ASSERT(asUintptr() - dec * sizeof(T) <= asUintptr());
      return create(ptr - dec);
    }

    /*
     * You can assign a raw pointer into a RangedPtr if the raw pointer is
     * within the range specified at creation.
     */
    template <typename U>
    RangedPtr<T>& operator=(U* p) {
      *this = create(p);
      return *this;
    }

    template <typename U>
    RangedPtr<T>& operator=(const RangedPtr<U>& p) {
      MOZ_ASSERT(rangeStart <= p.ptr);
      MOZ_ASSERT(p.ptr <= rangeEnd);
      ptr = p.ptr;
      checkSanity();
      return *this;
    }

    RangedPtr<T>& operator++() {
      return (*this += 1);
    }

    RangedPtr<T> operator++(int) {
      RangedPtr<T> rcp = *this;
      ++*this;
      return rcp;
    }

    RangedPtr<T>& operator--() {
      return (*this -= 1);
    }

    RangedPtr<T> operator--(int) {
      RangedPtr<T> rcp = *this;
      --*this;
      return rcp;
    }

    RangedPtr<T>& operator+=(size_t inc) {
      *this = *this + inc;
      return *this;
    }

    RangedPtr<T>& operator-=(size_t dec) {
      *this = *this - dec;
      return *this;
    }

    T& operator[](int index) const {
      MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
      return *create(ptr + index);
    }

    T& operator*() const {
      return *ptr;
    }

    template <typename U>
    bool operator==(const RangedPtr<U>& other) const {
      return ptr == other.ptr;
    }
    template <typename U>
    bool operator!=(const RangedPtr<U>& other) const {
      return !(*this == other);
    }

    template<typename U>
    bool operator==(const U* u) const {
      return ptr == u;
    }
    template<typename U>
    bool operator!=(const U* u) const {
      return !(*this == u);
    }

    template <typename U>
    bool operator<(const RangedPtr<U>& other) const {
      return ptr < other.ptr;
    }
    template <typename U>
    bool operator<=(const RangedPtr<U>& other) const {
      return ptr <= other.ptr;
    }

    template <typename U>
    bool operator>(const RangedPtr<U>& other) const {
      return ptr > other.ptr;
    }
    template <typename U>
    bool operator>=(const RangedPtr<U>& other) const {
      return ptr >= other.ptr;
    }

    size_t operator-(const RangedPtr<T>& other) const {
      MOZ_ASSERT(ptr >= other.ptr);
      return PointerRangeSize(other.ptr, ptr);
    }

  private:
    RangedPtr() MOZ_DELETE;
    T* operator&() MOZ_DELETE;
};

} /* namespace mozilla */

#endif  /* mozilla_RangedPtr_h_ */
