Files
carbon-lang/toolchain/common/index_base.h
T
Jon Ross-Perkins 2a163ca6cd Refactor the node stack into its own class. (#2505)
Currently, there's a mix of accessing node_stack_ both directly and indirectly, and there are already several Push/Pop methods to help wrap the behavior. However, there's also direct access because of shifting over time, as well as variations in _how_ the stack is used.

This migrates to a separate class in order to make a more specific contract for the API. It cleans up existing uses and adds APIs where needed.
2023-01-05 15:16:05 -08:00

87 lines
2.8 KiB
C++

// 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_COMMON_INDEX_BASE_H_
#define CARBON_TOOLCHAIN_COMMON_INDEX_BASE_H_
#include <type_traits>
#include "common/ostream.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Format.h"
namespace Carbon {
template <typename DataType>
class DataIterator;
// A lightweight handle to an item in a vector.
//
// DataIndex is designed to be passed by value, not reference or pointer. They
// are also designed to be small and efficient to store in data structures.
struct IndexBase {
static constexpr int32_t InvalidIndex = -1;
constexpr IndexBase() : index(InvalidIndex) {}
constexpr explicit IndexBase(int index) : index(index) {}
auto Print(llvm::raw_ostream& output) const -> void {
if (is_valid()) {
output << index;
} else {
output << "<invalid>";
}
}
auto is_valid() const -> bool { return index != InvalidIndex; }
int32_t index;
};
// Like IndexBase, but also provides < and > comparison operators.
struct ComparableIndexBase : public IndexBase {
using IndexBase::IndexBase;
};
// Equality comparison for both IndexBase and ComparableIndexBase.
template <typename IndexType,
typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
nullptr>
auto operator==(IndexType lhs, IndexType rhs) -> bool {
return lhs.index == rhs.index;
}
template <typename IndexType,
typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
nullptr>
auto operator!=(IndexType lhs, IndexType rhs) -> bool {
return lhs.index != rhs.index;
}
// The < and > comparisons for only ComparableIndexBase.
template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
ComparableIndexBase, IndexType>>* = nullptr>
auto operator<(IndexType lhs, IndexType rhs) -> bool {
return lhs.index < rhs.index;
}
template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
ComparableIndexBase, IndexType>>* = nullptr>
auto operator<=(IndexType lhs, IndexType rhs) -> bool {
return lhs.index <= rhs.index;
}
template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
ComparableIndexBase, IndexType>>* = nullptr>
auto operator>(IndexType lhs, IndexType rhs) -> bool {
return lhs.index > rhs.index;
}
template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
ComparableIndexBase, IndexType>>* = nullptr>
auto operator>=(IndexType lhs, IndexType rhs) -> bool {
return lhs.index >= rhs.index;
}
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_COMMON_INDEX_BASE_H_