/*
 * 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 {
 private:
  struct tag { };

 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>
  explicit constexpr ArrayRef(U (&array)[size],
                              typename std::enable_if<std::is_same<T, const U>::value, tag>::type
                                  t ATTRIBUTE_UNUSED = tag())
    : array_(array), size_(size) {
  }

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

  template <typename Alloc>
  explicit ArrayRef(std::vector<T, Alloc>& v)
      : array_(v.data()), size_(v.size()) {
  }

  template <typename U, typename Alloc>
  explicit ArrayRef(const std::vector<U, Alloc>& v,
                    typename std::enable_if<std::is_same<T, const U>::value, tag>::type
                        t ATTRIBUTE_UNUSED = tag())
      : 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) const {
    return SubArray(pos, size_ - pos);
  }
  ArrayRef SubArray(size_type pos, size_type length) const {
    DCHECK_LE(pos, size());
    DCHECK_LE(length, size() - pos);
    return ArrayRef(array_ + 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_
