index_base.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_
  5. #define CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_
  6. #include <type_traits>
  7. #include "common/ostream.h"
  8. #include "llvm/ADT/DenseMapInfo.h"
  9. namespace Carbon {
  10. template <typename DataType>
  11. class DataIterator;
  12. // A lightweight handle to an item in a vector.
  13. //
  14. // DataIndex is designed to be passed by value, not reference or pointer. They
  15. // are also designed to be small and efficient to store in data structures.
  16. struct IndexBase : public Printable<IndexBase> {
  17. static constexpr int32_t InvalidIndex = -1;
  18. IndexBase() = delete;
  19. constexpr explicit IndexBase(int index) : index(index) {}
  20. auto Print(llvm::raw_ostream& output) const -> void {
  21. if (is_valid()) {
  22. output << index;
  23. } else {
  24. output << "<invalid>";
  25. }
  26. }
  27. auto is_valid() const -> bool { return index != InvalidIndex; }
  28. int32_t index;
  29. };
  30. // Like IndexBase, but also provides < and > comparison operators.
  31. struct ComparableIndexBase : public IndexBase {
  32. using IndexBase::IndexBase;
  33. };
  34. // Equality comparison for both IndexBase and ComparableIndexBase.
  35. template <typename IndexType,
  36. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  37. nullptr>
  38. auto operator==(IndexType lhs, IndexType rhs) -> bool {
  39. return lhs.index == rhs.index;
  40. }
  41. template <typename IndexType,
  42. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  43. nullptr>
  44. auto operator!=(IndexType lhs, IndexType rhs) -> bool {
  45. return lhs.index != rhs.index;
  46. }
  47. // The < and > comparisons for only ComparableIndexBase.
  48. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  49. ComparableIndexBase, IndexType>>* = nullptr>
  50. auto operator<(IndexType lhs, IndexType rhs) -> bool {
  51. return lhs.index < rhs.index;
  52. }
  53. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  54. ComparableIndexBase, IndexType>>* = nullptr>
  55. auto operator<=(IndexType lhs, IndexType rhs) -> bool {
  56. return lhs.index <= rhs.index;
  57. }
  58. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  59. ComparableIndexBase, IndexType>>* = nullptr>
  60. auto operator>(IndexType lhs, IndexType rhs) -> bool {
  61. return lhs.index > rhs.index;
  62. }
  63. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  64. ComparableIndexBase, IndexType>>* = nullptr>
  65. auto operator>=(IndexType lhs, IndexType rhs) -> bool {
  66. return lhs.index >= rhs.index;
  67. }
  68. // Provides base support for use of IndexBase types as DenseMap/DenseSet keys.
  69. //
  70. // Usage (in global namespace):
  71. // template <>
  72. // struct llvm::DenseMapInfo<Carbon::MyType>
  73. // : public Carbon::IndexMapInfo<Carbon::MyType> {};
  74. template <typename Index>
  75. struct IndexMapInfo {
  76. static inline auto getEmptyKey() -> Index {
  77. return Index(llvm::DenseMapInfo<int32_t>::getEmptyKey());
  78. }
  79. static inline auto getTombstoneKey() -> Index {
  80. return Index(llvm::DenseMapInfo<int32_t>::getTombstoneKey());
  81. }
  82. static auto getHashValue(const Index& val) -> unsigned {
  83. return llvm::DenseMapInfo<int32_t>::getHashValue(val.index);
  84. }
  85. static auto isEqual(const Index& lhs, const Index& rhs) -> bool {
  86. return lhs == rhs;
  87. }
  88. };
  89. } // namespace Carbon
  90. #endif // CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_