blob: bd2c4df2a0f02e52c34cc6cc17bed8d6fed10c05 [file] [log] [blame]
// 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_