// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FBL_ARRAY_H_
#define FBL_ARRAY_H_

#include <zircon/assert.h>
#include <fbl/macros.h>
#include <type_traits>

namespace fbl {

// |Array| is lightweight movable container that takes ownership of an array.
// At destruction or when reset() is invoked, it uses delete[] to release the owned array.
template <typename T>
class Array {
public:
    constexpr Array() : ptr_(nullptr), count_(0U) {}
    constexpr Array(decltype(nullptr)) : Array() {}

    Array(T* array, size_t count) : ptr_(array), count_(count) {}

    Array(Array&& other) : ptr_(nullptr), count_(other.count_) {
        ptr_ = other.release();
    }

    // Move constructor allowing us to move from Array<T> to Array<const T>
    template <typename OtherType>
    Array(Array<OtherType>&& other)
            : ptr_(nullptr), count_(other.size()) {
        static_assert(!std::is_const<OtherType>::value && std::is_same<const OtherType, T>::value);

        ptr_ = other.release();
    }

    size_t size() const {
        return count_;
    }

    ~Array() {
        reset();
    }

    Array& operator=(Array&& o) {
        auto count = o.count_;
        reset(o.release(), count);
        return *this;
    }

    // Move operator allowing us to move from Array<T> to Array<const T>
    template <typename OtherType>
    Array& operator=(Array<OtherType>&& o) {
        static_assert(!std::is_const<OtherType>::value && std::is_same<const OtherType, T>::value);

        auto count = o.size();
        reset(o.release(), count);
        return *this;
    }

    // move semantics only
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Array);

    T* release() {
        T* t = ptr_;
        ptr_ = nullptr;
        count_ = 0;
        return t;
    }

    void reset() {
        reset(nullptr, 0U);
    }

    void reset(T* t, size_t count) {
        T* ptr = ptr_;
        ptr_ = t;
        count_ = count;
        delete[] ptr;
    }

    void swap(Array& other) {
        T* t = ptr_;
        ptr_ = other.ptr_;
        other.ptr_ = t;
        size_t c = count_;
        count_ = other.count_;
        other.count_ = c;
    }

    T* get() const {
        return ptr_;
    }

    explicit operator bool() const {
        return static_cast<bool>(ptr_);
    }

    T& operator[](size_t i) const {
        ZX_DEBUG_ASSERT(i < count_);
        return ptr_[i];
    }

    T* begin() const {
        return ptr_;
    }

    T* end() const {
        return &ptr_[count_];
    }

private:
    T* ptr_;
    size_t count_;
};

}  // namespace fbl

#endif  // FBL_ARRAY_H_
