/*
 * Copyright (C) 2015 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_RUNTIME_LENGTH_PREFIXED_ARRAY_H_
#define ART_RUNTIME_LENGTH_PREFIXED_ARRAY_H_

#include <stddef.h>  // for offsetof()

#include "stride_iterator.h"
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/iteration_range.h"

namespace art {

template<typename T>
class LengthPrefixedArray {
 public:
  explicit LengthPrefixedArray(size_t length)
      : size_(dchecked_integral_cast<uint32_t>(length)) {}

  T& At(size_t index, size_t element_size = sizeof(T), size_t alignment = alignof(T)) {
    DCHECK_LT(index, size_);
    return AtUnchecked(index, element_size, alignment);
  }

  const T& At(size_t index, size_t element_size = sizeof(T), size_t alignment = alignof(T)) const {
    DCHECK_LT(index, size_);
    return AtUnchecked(index, element_size, alignment);
  }

  StrideIterator<T> begin(size_t element_size = sizeof(T), size_t alignment = alignof(T)) {
    return StrideIterator<T>(&AtUnchecked(0, element_size, alignment), element_size);
  }

  StrideIterator<const T> begin(size_t element_size = sizeof(T),
                                size_t alignment = alignof(T)) const {
    return StrideIterator<const T>(&AtUnchecked(0, element_size, alignment), element_size);
  }

  StrideIterator<T> end(size_t element_size = sizeof(T), size_t alignment = alignof(T)) {
    return StrideIterator<T>(&AtUnchecked(size_, element_size, alignment), element_size);
  }

  StrideIterator<const T> end(size_t element_size = sizeof(T),
                              size_t alignment = alignof(T)) const {
    return StrideIterator<const T>(&AtUnchecked(size_, element_size, alignment), element_size);
  }

  static size_t OffsetOfElement(size_t index,
                                size_t element_size = sizeof(T),
                                size_t alignment = alignof(T)) {
    DCHECK_ALIGNED_PARAM(element_size, alignment);
    return RoundUp(offsetof(LengthPrefixedArray<T>, data), alignment) + index * element_size;
  }

  static size_t ComputeSize(size_t num_elements,
                            size_t element_size = sizeof(T),
                            size_t alignment = alignof(T)) {
    size_t result = OffsetOfElement(num_elements, element_size, alignment);
    DCHECK_ALIGNED_PARAM(result, alignment);
    return result;
  }

  size_t size() const {
    return size_;
  }

  // Update the length but does not reallocate storage.
  void SetSize(size_t length) {
    size_ = dchecked_integral_cast<uint32_t>(length);
  }

 private:
  T& AtUnchecked(size_t index, size_t element_size, size_t alignment) {
    return *reinterpret_cast<T*>(
        reinterpret_cast<uintptr_t>(this) + OffsetOfElement(index, element_size, alignment));
  }

  const T& AtUnchecked(size_t index, size_t element_size, size_t alignment) const {
    return *reinterpret_cast<T*>(
        reinterpret_cast<uintptr_t>(this) + OffsetOfElement(index, element_size, alignment));
  }

  uint32_t size_;
  uint8_t data[0];
};

// Returns empty iteration range if the array is null.
template<typename T>
IterationRange<StrideIterator<T>> MakeIterationRangeFromLengthPrefixedArray(
    LengthPrefixedArray<T>* arr, size_t element_size = sizeof(T), size_t alignment = alignof(T)) {
  return arr != nullptr ?
      MakeIterationRange(arr->begin(element_size, alignment), arr->end(element_size, alignment)) :
      MakeEmptyIterationRange(StrideIterator<T>(nullptr, 0));
}

}  // namespace art

#endif  // ART_RUNTIME_LENGTH_PREFIXED_ARRAY_H_
