// Copyright 2017 The Abseil 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.
//
// -----------------------------------------------------------------------------
// File: fixed_array.h
// -----------------------------------------------------------------------------
//
// A `FixedArray<T>` represents a non-resizable array of `T` where the length of
// the array can be determined at run-time. It is a good replacement for
// non-standard and deprecated uses of `alloca()` and variable length arrays
// within the GCC extension. (See
// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html).
//
// `FixedArray` allocates small arrays inline, keeping performance fast by
// avoiding heap operations. It also helps reduce the chances of
// accidentally overflowing your stack if large input is passed to
// your function.

#ifndef ABSL_CONTAINER_FIXED_ARRAY_H_
#define ABSL_CONTAINER_FIXED_ARRAY_H_

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <type_traits>

#include "absl/algorithm/algorithm.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/memory/memory.h"

namespace absl {

constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1);

// -----------------------------------------------------------------------------
// FixedArray
// -----------------------------------------------------------------------------
//
// A `FixedArray` provides a run-time fixed-size array, allocating small arrays
// inline for efficiency and correctness.
//
// Most users should not specify an `inline_elements` argument and let
// `FixedArray<>` automatically determine the number of elements
// to store inline based on `sizeof(T)`. If `inline_elements` is specified, the
// `FixedArray<>` implementation will inline arrays of
// length <= `inline_elements`.
//
// Note that a `FixedArray` constructed with a `size_type` argument will
// default-initialize its values by leaving trivially constructible types
// uninitialized (e.g. int, int[4], double), and others default-constructed.
// This matches the behavior of c-style arrays and `std::array`, but not
// `std::vector`.
//
// Note that `FixedArray` does not provide a public allocator; if it requires a
// heap allocation, it will do so with global `::operator new[]()` and
// `::operator delete[]()`, even if T provides class-scope overrides for these
// operators.
template <typename T, size_t inlined = kFixedArrayUseDefault>
class FixedArray {
  static constexpr size_t kInlineBytesDefault = 256;

  // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
  // but this seems to be mostly pedantic.
  template <typename Iter>
  using EnableIfForwardIterator = typename std::enable_if<
      std::is_convertible<
          typename std::iterator_traits<Iter>::iterator_category,
          std::forward_iterator_tag>::value,
      int>::type;

 public:
  // For playing nicely with stl:
  using value_type = T;
  using iterator = T*;
  using const_iterator = const T*;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  using reference = T&;
  using const_reference = const T&;
  using pointer = T*;
  using const_pointer = const T*;
  using difference_type = ptrdiff_t;
  using size_type = size_t;

  static constexpr size_type inline_elements =
      inlined == kFixedArrayUseDefault
          ? kInlineBytesDefault / sizeof(value_type)
          : inlined;

  FixedArray(const FixedArray& other) : rep_(other.begin(), other.end()) {}
  FixedArray(FixedArray&& other) noexcept(
  // clang-format off
      absl::allocator_is_nothrow<std::allocator<value_type>>::value &&
  // clang-format on
          std::is_nothrow_move_constructible<value_type>::value)
      : rep_(std::make_move_iterator(other.begin()),
             std::make_move_iterator(other.end())) {}

  // Creates an array object that can store `n` elements.
  // Note that trivially constructible elements will be uninitialized.
  explicit FixedArray(size_type n) : rep_(n) {}

  // Creates an array initialized with `n` copies of `val`.
  FixedArray(size_type n, const value_type& val) : rep_(n, val) {}

  // Creates an array initialized with the elements from the input
  // range. The array's size will always be `std::distance(first, last)`.
  // REQUIRES: Iter must be a forward_iterator or better.
  template <typename Iter, EnableIfForwardIterator<Iter> = 0>
  FixedArray(Iter first, Iter last) : rep_(first, last) {}

  // Creates the array from an initializer_list.
  FixedArray(std::initializer_list<T> init_list)
      : FixedArray(init_list.begin(), init_list.end()) {}

  ~FixedArray() {}

  // Assignments are deleted because they break the invariant that the size of a
  // `FixedArray` never changes.
  void operator=(FixedArray&&) = delete;
  void operator=(const FixedArray&) = delete;

  // FixedArray::size()
  //
  // Returns the length of the fixed array.
  size_type size() const { return rep_.size(); }

  // FixedArray::max_size()
  //
  // Returns the largest possible value of `std::distance(begin(), end())` for a
  // `FixedArray<T>`. This is equivalent to the most possible addressable bytes
  // over the number of bytes taken by T.
  constexpr size_type max_size() const {
    return std::numeric_limits<difference_type>::max() / sizeof(value_type);
  }

  // FixedArray::empty()
  //
  // Returns whether or not the fixed array is empty.
  bool empty() const { return size() == 0; }

  // FixedArray::memsize()
  //
  // Returns the memory size of the fixed array in bytes.
  size_t memsize() const { return size() * sizeof(value_type); }

  // FixedArray::data()
  //
  // Returns a const T* pointer to elements of the `FixedArray`. This pointer
  // can be used to access (but not modify) the contained elements.
  const_pointer data() const { return AsValue(rep_.begin()); }

  // Overload of FixedArray::data() to return a T* pointer to elements of the
  // fixed array. This pointer can be used to access and modify the contained
  // elements.
  pointer data() { return AsValue(rep_.begin()); }

  // FixedArray::operator[]
  //
  // Returns a reference the ith element of the fixed array.
  // REQUIRES: 0 <= i < size()
  reference operator[](size_type i) {
    assert(i < size());
    return data()[i];
  }

  // Overload of FixedArray::operator()[] to return a const reference to the
  // ith element of the fixed array.
  // REQUIRES: 0 <= i < size()
  const_reference operator[](size_type i) const {
    assert(i < size());
    return data()[i];
  }

  // FixedArray::at
  //
  // Bounds-checked access.  Returns a reference to the ith element of the
  // fiexed array, or throws std::out_of_range
  reference at(size_type i) {
    if (ABSL_PREDICT_FALSE(i >= size())) {
      base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
    }
    return data()[i];
  }

  // Overload of FixedArray::at() to return a const reference to the ith element
  // of the fixed array.
  const_reference at(size_type i) const {
    if (ABSL_PREDICT_FALSE(i >= size())) {
      base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check");
    }
    return data()[i];
  }

  // FixedArray::front()
  //
  // Returns a reference to the first element of the fixed array.
  reference front() { return *begin(); }

  // Overload of FixedArray::front() to return a reference to the first element
  // of a fixed array of const values.
  const_reference front() const { return *begin(); }

  // FixedArray::back()
  //
  // Returns a reference to the last element of the fixed array.
  reference back() { return *(end() - 1); }

  // Overload of FixedArray::back() to return a reference to the last element
  // of a fixed array of const values.
  const_reference back() const { return *(end() - 1); }

  // FixedArray::begin()
  //
  // Returns an iterator to the beginning of the fixed array.
  iterator begin() { return data(); }

  // Overload of FixedArray::begin() to return a const iterator to the
  // beginning of the fixed array.
  const_iterator begin() const { return data(); }

  // FixedArray::cbegin()
  //
  // Returns a const iterator to the beginning of the fixed array.
  const_iterator cbegin() const { return begin(); }

  // FixedArray::end()
  //
  // Returns an iterator to the end of the fixed array.
  iterator end() { return data() + size(); }

  // Overload of FixedArray::end() to return a const iterator to the end of the
  // fixed array.
  const_iterator end() const { return data() + size(); }

  // FixedArray::cend()
  //
  // Returns a const iterator to the end of the fixed array.
  const_iterator cend() const { return end(); }

  // FixedArray::rbegin()
  //
  // Returns a reverse iterator from the end of the fixed array.
  reverse_iterator rbegin() { return reverse_iterator(end()); }

  // Overload of FixedArray::rbegin() to return a const reverse iterator from
  // the end of the fixed array.
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }

  // FixedArray::crbegin()
  //
  // Returns a const reverse iterator from the end of the fixed array.
  const_reverse_iterator crbegin() const { return rbegin(); }

  // FixedArray::rend()
  //
  // Returns a reverse iterator from the beginning of the fixed array.
  reverse_iterator rend() { return reverse_iterator(begin()); }

  // Overload of FixedArray::rend() for returning a const reverse iterator
  // from the beginning of the fixed array.
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

  // FixedArray::crend()
  //
  // Returns a reverse iterator from the beginning of the fixed array.
  const_reverse_iterator crend() const { return rend(); }

  // FixedArray::fill()
  //
  // Assigns the given `value` to all elements in the fixed array.
  void fill(const T& value) { std::fill(begin(), end(), value); }

  // Relational operators. Equality operators are elementwise using
  // `operator==`, while order operators order FixedArrays lexicographically.
  friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) {
    return absl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  }

  friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) {
    return !(lhs == rhs);
  }

  friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) {
    return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
                                        rhs.end());
  }

  friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) {
    return rhs < lhs;
  }

  friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) {
    return !(rhs < lhs);
  }

  friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
    return !(lhs < rhs);
  }

 private:
  // HolderTraits
  //
  // Wrapper to hold elements of type T for the case where T is an array type.
  // If 'T' is an array type, HolderTraits::type is a struct with a 'T v;'.
  // Otherwise, HolderTraits::type is simply 'T'.
  //
  // Maintainer's Note: The simpler solution would be to simply wrap T in a
  // struct whether it's an array or not: 'struct Holder { T v; };', but
  // that causes some paranoid diagnostics to misfire about uses of data(),
  // believing that 'data()' (aka '&rep_.begin().v') is a pointer to a single
  // element, rather than the packed array that it really is.
  // e.g.:
  //
  //     FixedArray<char> buf(1);
  //     sprintf(buf.data(), "foo");
  //
  //     error: call to int __builtin___sprintf_chk(etc...)
  //     will always overflow destination buffer [-Werror]
  //
  class HolderTraits {
    template <typename U>
    struct SelectImpl {
      using type = U;
      static pointer AsValue(type* p) { return p; }
    };

    // Partial specialization for elements of array type.
    template <typename U, size_t N>
    struct SelectImpl<U[N]> {
      struct Holder { U v[N]; };
      using type = Holder;
      static pointer AsValue(type* p) { return &p->v; }
    };
    using Impl = SelectImpl<value_type>;

   public:
    using type = typename Impl::type;

    static pointer AsValue(type *p) { return Impl::AsValue(p); }

    // TODO(billydonahue): fix the type aliasing violation
    // this assertion hints at.
    static_assert(sizeof(type) == sizeof(value_type),
                  "Holder must be same size as value_type");
  };

  using Holder = typename HolderTraits::type;
  static pointer AsValue(Holder *p) { return HolderTraits::AsValue(p); }

  // InlineSpace
  //
  // Allocate some space, not an array of elements of type T, so that we can
  // skip calling the T constructors and destructors for space we never use.
  // How many elements should we store inline?
  //   a. If not specified, use a default of kInlineBytesDefault bytes (This is
  //   currently 256 bytes, which seems small enough to not cause stack overflow
  //   or unnecessary stack pollution, while still allowing stack allocation for
  //   reasonably long character arrays).
  //   b. Never use 0 length arrays (not ISO C++)
  //
  template <size_type N, typename = void>
  class InlineSpace {
   public:
    Holder* data() { return reinterpret_cast<Holder*>(space_.data()); }
    void AnnotateConstruct(size_t n) const { Annotate(n, true); }
    void AnnotateDestruct(size_t n) const { Annotate(n, false); }

   private:
#ifndef ADDRESS_SANITIZER
    void Annotate(size_t, bool) const { }
#else
    void Annotate(size_t n, bool creating) const {
      if (!n) return;
      const void* bot = &left_redzone_;
      const void* beg = space_.data();
      const void* end = space_.data() + n;
      const void* top = &right_redzone_ + 1;
      // args: (beg, end, old_mid, new_mid)
      if (creating) {
        ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, top, top, end);
        ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(bot, beg, beg, bot);
      } else {
        ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, top, end, top);
        ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(bot, beg, bot, beg);
      }
    }
#endif  // ADDRESS_SANITIZER

    using Buffer =
        typename std::aligned_storage<sizeof(Holder), alignof(Holder)>::type;

    ABSL_ADDRESS_SANITIZER_REDZONE(left_redzone_);
    std::array<Buffer, N> space_;
    ABSL_ADDRESS_SANITIZER_REDZONE(right_redzone_);
  };

  // specialization when N = 0.
  template <typename U>
  class InlineSpace<0, U> {
   public:
    Holder* data() { return nullptr; }
    void AnnotateConstruct(size_t) const {}
    void AnnotateDestruct(size_t) const {}
  };

  // Rep
  //
  // A const Rep object holds FixedArray's size and data pointer.
  //
  class Rep : public InlineSpace<inline_elements> {
   public:
    Rep(size_type n, const value_type& val) : n_(n), p_(MakeHolder(n)) {
      std::uninitialized_fill_n(p_, n, val);
    }

    explicit Rep(size_type n) : n_(n), p_(MakeHolder(n)) {
      // Loop optimizes to nothing for trivially constructible T.
      for (Holder* p = p_; p != p_ + n; ++p)
        // Note: no parens: default init only.
        // Also note '::' to avoid Holder class placement new operator.
        ::new (static_cast<void*>(p)) Holder;
    }

    template <typename Iter>
    Rep(Iter first, Iter last)
        : n_(std::distance(first, last)), p_(MakeHolder(n_)) {
      std::uninitialized_copy(first, last, AsValue(p_));
    }

    ~Rep() {
      // Destruction must be in reverse order.
      // Loop optimizes to nothing for trivially destructible T.
      for (Holder* p = end(); p != begin();) (--p)->~Holder();
      if (IsAllocated(size())) {
        std::allocator<Holder>().deallocate(p_, n_);
      } else {
        this->AnnotateDestruct(size());
      }
    }
    Holder* begin() const { return p_; }
    Holder* end() const { return p_ + n_; }
    size_type size() const { return n_; }

   private:
    Holder* MakeHolder(size_type n) {
      if (IsAllocated(n)) {
        return std::allocator<Holder>().allocate(n);
      } else {
        this->AnnotateConstruct(n);
        return this->data();
      }
    }

    bool IsAllocated(size_type n) const { return n > inline_elements; }

    const size_type n_;
    Holder* const p_;
  };


  // Data members
  Rep rep_;
};

template <typename T, size_t N>
constexpr size_t FixedArray<T, N>::inline_elements;

template <typename T, size_t N>
constexpr size_t FixedArray<T, N>::kInlineBytesDefault;

}  // namespace absl
#endif  // ABSL_CONTAINER_FIXED_ARRAY_H_
