/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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 ART_COMPILER_UTILS_ARRAY_REF_H_
#define ART_COMPILER_UTILS_ARRAY_REF_H_

#include <type_traits>
#include <vector>

#include "base/logging.h"

namespace art {

/**
 * @brief A container that references an array.
 *
 * @details The template class ArrayRef provides a container that references
 * an external array. This external array must remain alive while the ArrayRef
 * object is in use. The external array may be a std::vector<>-backed storage
 * or any other contiguous chunk of memory but that memory must remain valid,
 * i.e. the std::vector<> must not be resized for example.
 *
 * Except for copy/assign and insert/erase/capacity functions, the interface
 * is essentially the same as std::vector<>. Since we don't want to throw
 * exceptions, at() is also excluded.
 */
template <typename T>
class ArrayRef {
 public:
  typedef T value_type;
  typedef T& reference;
  typedef const T& const_reference;
  typedef T* pointer;
  typedef const T* const_pointer;
  typedef T* iterator;
  typedef const T* const_iterator;
  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  typedef ptrdiff_t difference_type;
  typedef size_t size_type;

  // Constructors.

  constexpr ArrayRef()
      : array_(nullptr), size_(0u) {
  }

  template <size_t size>
  explicit constexpr ArrayRef(T (&array)[size])
      : array_(array), size_(size) {
  }

  template <typename U,
            size_t size,
            typename = typename std::enable_if<std::is_same<T, const U>::value>::type>
  explicit constexpr ArrayRef(U (&array)[size])
      : array_(array), size_(size) {
  }

  constexpr ArrayRef(T* array_in, size_t size_in)
      : array_(array_in), size_(size_in) {
  }

  template <typename Vector,
            typename = typename std::enable_if<
                std::is_same<typename Vector::value_type, value_type>::value>::type>
  explicit ArrayRef(Vector& v)
      : array_(v.data()), size_(v.size()) {
  }

  template <typename Vector,
            typename = typename std::enable_if<
                std::is_same<
                    typename std::add_const<typename Vector::value_type>::type,
                    value_type>::value>::type>
  explicit ArrayRef(const Vector& v)
      : array_(v.data()), size_(v.size()) {
  }

  ArrayRef(const ArrayRef&) = default;

  // Assignment operators.

  ArrayRef& operator=(const ArrayRef& other) {
    array_ = other.array_;
    size_ = other.size_;
    return *this;
  }

  template <typename U>
  typename std::enable_if<std::is_same<T, const U>::value, ArrayRef>::type&
  operator=(const ArrayRef<U>& other) {
    return *this = ArrayRef(other);
  }

  // Destructor.
  ~ArrayRef() = default;

  // Iterators.
  iterator begin() { return array_; }
  const_iterator begin() const { return array_; }
  const_iterator cbegin() const { return array_; }
  iterator end() { return array_ + size_; }
  const_iterator end() const { return array_ + size_; }
  const_iterator cend() const { return array_ + size_; }
  reverse_iterator rbegin() { return reverse_iterator(end()); }
  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
  const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
  reverse_iterator rend() { return reverse_iterator(begin()); }
  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
  const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }

  // Size.
  size_type size() const { return size_; }
  bool empty() const { return size() == 0u; }

  // Element access. NOTE: Not providing at().

  reference operator[](size_type n) {
    DCHECK_LT(n, size_);
    return array_[n];
  }

  const_reference operator[](size_type n) const {
    DCHECK_LT(n, size_);
    return array_[n];
  }

  reference front() {
    DCHECK_NE(size_, 0u);
    return array_[0];
  }

  const_reference front() const {
    DCHECK_NE(size_, 0u);
    return array_[0];
  }

  reference back() {
    DCHECK_NE(size_, 0u);
    return array_[size_ - 1u];
  }

  const_reference back() const {
    DCHECK_NE(size_, 0u);
    return array_[size_ - 1u];
  }

  value_type* data() { return array_; }
  const value_type* data() const { return array_; }

  ArrayRef SubArray(size_type pos) {
    return SubArray(pos, size() - pos);
  }
  ArrayRef<const T> SubArray(size_type pos) const {
    return SubArray(pos, size() - pos);
  }
  ArrayRef SubArray(size_type pos, size_type length) {
    DCHECK_LE(pos, size());
    DCHECK_LE(length, size() - pos);
    return ArrayRef(data() + pos, length);
  }
  ArrayRef<const T> SubArray(size_type pos, size_type length) const {
    DCHECK_LE(pos, size());
    DCHECK_LE(length, size() - pos);
    return ArrayRef<const T>(data() + pos, length);
  }

 private:
  T* array_;
  size_t size_;
};

template <typename T>
bool operator==(const ArrayRef<T>& lhs, const ArrayRef<T>& rhs) {
  return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}

template <typename T>
bool operator!=(const ArrayRef<T>& lhs, const ArrayRef<T>& rhs) {
  return !(lhs == rhs);
}

}  // namespace art


#endif  // ART_COMPILER_UTILS_ARRAY_REF_H_
