// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #ifndef CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_ #define CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_ #include #include #include #include #include "common/ostream.h" #include "llvm/ADT/iterator.h" namespace Carbon { template class DataIterator; // Non-templated portions of `IdBase`. struct AnyIdBase { static constexpr int32_t NoneIndex = -1; AnyIdBase() = delete; constexpr explicit AnyIdBase(int index) : index(index) {} constexpr auto has_value() const -> bool { return index != NoneIndex; } int32_t index; }; // A lightweight handle to an item identified by an opaque ID. // // This class is intended to be derived from by classes representing a specific // kind of ID, whose meaning as an integer is an implementation detail of the // type that vends the IDs. Typically this will be a vector index. // // Classes derived from IdBase are designed to be passed by value, not // reference or pointer. They are also designed to be small and efficient to // store in data structures. // // This uses CRTP for the `Print` function. Children should have: // static constexpr llvm::StringLiteral Label = "my_label"; // Children can also define their own `Print` function, removing the dependency // on `Label`. template struct IdBase : public AnyIdBase, public Printable { using AnyIdBase::AnyIdBase; // Provide a standard `None` mapping to `NoneIndex`. // // This uses a `&` to trigger slightly different instantiation behaviors in // Clang. For context on why this is needed, see http://wg21.link/CWG2800. // NOLINTNEXTLINE(readability-identifier-naming) static const IdT& None; auto Print(llvm::raw_ostream& out) const -> void { out << IdT::Label; if (has_value()) { out << index; } else { out << ""; } } // Support simple equality comparison for ID types. friend constexpr auto operator==(IdBase lhs, IdBase rhs) -> bool { return lhs.index == rhs.index; } }; template constexpr const IdT& IdBase::None = IdT(NoneIndex); // A lightweight handle to an item that behaves like an index. // // Unlike IdBase, classes derived from IndexBase are not completely opaque, and // provide at least an ordering between indexes that has meaning to an API // user. Additional semantics may be specified by the derived class. template struct IndexBase : public IdBase { using IdBase::IdBase; // Support relational comparisons for index types. friend auto operator<=>(IndexBase lhs, IndexBase rhs) -> std::strong_ordering { return lhs.index <=> rhs.index; } }; // A random-access iterator for arrays using IndexBase-derived types. template class IndexIterator : public llvm::iterator_facade_base, std::random_access_iterator_tag, const IndexT, int>, public Printable> { public: IndexIterator() = delete; explicit IndexIterator(IndexT index) : index_(index) {} friend auto operator==(const IndexIterator& lhs, const IndexIterator& rhs) -> bool { return lhs.index_ == rhs.index_; } friend auto operator<=>(const IndexIterator& lhs, const IndexIterator& rhs) -> std::strong_ordering { return lhs.index_ <=> rhs.index_; } auto operator*() const -> const IndexT& { return index_; } using llvm::iterator_facade_base::operator-; friend auto operator-(const IndexIterator& lhs, const IndexIterator& rhs) -> int { return lhs.index_.index - rhs.index_.index; } auto operator+=(int n) -> IndexIterator& { index_.index += n; return *this; } auto operator-=(int n) -> IndexIterator& { index_.index -= n; return *this; } // Prints the raw token index. auto Print(llvm::raw_ostream& output) const -> void { output << index_.index; } private: IndexT index_; }; } // namespace Carbon #endif // CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_

AltStyle によって変換されたページ (->オリジナル) /