blob: fed8af9321ff910abe7e6c2a4bfd4db99b14c990 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_WORD_VIEW_H_
#define ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_WORD_VIEW_H_
#include <zircon/assert.h>
#include <iterator>
#include <string_view>
// This provides a container-like view of string_view for each
// whitespace-separated word in the overall line.
class WordView {
public:
class iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = std::string_view;
using pointer = value_type;
using reference = value_type;
using difference_type = ptrdiff_t;
iterator() = default;
iterator(const iterator&) = default;
iterator& operator=(const iterator&) = default;
~iterator() { Check(); }
bool operator==(const iterator& other) const { return rest_.data() == other.rest_.data(); }
bool operator!=(const iterator& other) const { return !(*this == other); }
// Note that ++end() just yields end(), which begin() relies on (below).
iterator& operator++(); // prefix
iterator operator++(int) { // postfix
auto old = *this;
++*this;
return old;
}
std::string_view operator*() const { return word_; }
private:
// This is called only by begin() and end(), below.
friend WordView;
iterator(std::string_view line, std::string_view word) : rest_(line), word_(word) {}
// Check invariants: Current word_ is a subset of the rest_.
void Check() const {
ZX_DEBUG_ASSERT(word_.begin() >= rest_.begin());
ZX_DEBUG_ASSERT(word_.end() <= rest_.end());
}
// rest_ includes the current word_.
std::string_view rest_, word_;
};
using const_iterator = iterator;
WordView() = delete;
explicit WordView(std::string_view line) : line_(line) {}
iterator begin() const { return ++iterator{line_, line_.substr(0, 0)}; }
iterator end() const {
auto limit = line_.substr(line_.size());
return iterator{limit, limit};
}
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
private:
std::string_view line_;
};
#endif // ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_WORD_VIEW_H_