blob: b7a2616f02c4661d641f1ae65e077658daaea990 [file] [log] [blame]
// Copyright 2017 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 PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_
#define PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_
#include <algorithm>
#include <iterator>
#include <lib/fxl/logging.h>
namespace convert {
// View over the given collection. Doesn't take ownership of the collection that
// must outlives this class.
//
// Single-argument constructor is marked as NOLINT to suppress
// `google-explicit-constructor` clang-tidy warning - in this case the implicit
// conversion is intended.
template <typename T>
class CollectionView {
public:
using iterator = typename T::iterator;
using const_iterator = typename T::const_iterator;
CollectionView(T& collection) // NOLINT
: collection_(collection),
begin_(std::begin(collection)),
end_(std::end(collection)) {}
CollectionView(T& collection, iterator begin, iterator end)
: collection_(collection),
begin_(std::move(begin)),
end_(std::move(end)) {}
CollectionView(const CollectionView& collection) = default;
CollectionView& operator=(const CollectionView& collection) = default;
const_iterator begin() const { return begin_; }
const_iterator end() const { return end_; }
iterator begin() { return begin_; }
iterator end() { return end_; }
// Returns a view over this view with the first element removed.
CollectionView Tail() const {
if (begin_ == end_) {
return CollectionView<T>(collection_, end_, end_);
}
return CollectionView(collection_, std::next(begin_), end_);
}
// Returns a sub view of this view.
CollectionView SubCollection(size_t begin, size_t length) const {
if (begin >= size()) {
return CollectionView<T>(collection_, end_, end_);
}
auto begin_it = std::next(begin_, begin);
size_t final_length =
std::min(length, static_cast<size_t>(std::distance(begin_it, end_)));
return CollectionView(collection_, begin_it,
std::next(begin_it, final_length));
}
const auto& operator[](size_t pos) const {
FXL_DCHECK(pos < size());
return *std::next(begin_, pos);
}
auto& operator[](size_t pos) {
FXL_DCHECK(pos < static_cast<size_t>(std::distance(begin_, end_)));
return *std::next(begin_, pos);
}
bool empty() const { return begin_ == end_; }
size_t size() const { return std::distance(begin_, end_); }
private:
T& collection_;
iterator begin_;
iterator end_;
};
} // namespace convert
#endif // PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_