index_base.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 identified by an opaque ID.
  13. //
  14. // This class is intended to be derived from by classes representing a specific
  15. // kind of ID, whose meaning as an integer is an implementation detail of the
  16. // type that vends the IDs. Typically this will be a vector index.
  17. //
  18. // Classes derived from IdBase are designed to be passed by value, not
  19. // reference or pointer. They are also designed to be small and efficient to
  20. // store in data structures.
  21. struct IdBase : public Printable<IdBase> {
  22. static constexpr int32_t InvalidIndex = -1;
  23. IdBase() = delete;
  24. constexpr explicit IdBase(int index) : index(index) {}
  25. auto Print(llvm::raw_ostream& output) const -> void {
  26. if (is_valid()) {
  27. output << index;
  28. } else {
  29. output << "<invalid>";
  30. }
  31. }
  32. auto is_valid() const -> bool { return index != InvalidIndex; }
  33. int32_t index;
  34. };
  35. // A lightweight handle to an item that behaves like an index.
  36. //
  37. // Unlike IdBase, classes derived from IndexBase are not completely opaque, and
  38. // provide at least an ordering between indexes that has meaning to an API
  39. // user. Additional semantics may be specified by the derived class.
  40. struct IndexBase : public IdBase {
  41. using IdBase::IdBase;
  42. };
  43. // Equality comparison for both IdBase and IndexBase.
  44. template <
  45. typename IndexType,
  46. typename std::enable_if_t<std::is_base_of_v<IdBase, IndexType>>* = nullptr>
  47. auto operator==(IndexType lhs, IndexType rhs) -> bool {
  48. return lhs.index == rhs.index;
  49. }
  50. template <
  51. typename IndexType,
  52. typename std::enable_if_t<std::is_base_of_v<IdBase, IndexType>>* = nullptr>
  53. auto operator!=(IndexType lhs, IndexType rhs) -> bool {
  54. return lhs.index != rhs.index;
  55. }
  56. // The < and > comparisons for only IndexBase.
  57. template <typename IndexType,
  58. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  59. nullptr>
  60. auto operator<(IndexType lhs, IndexType rhs) -> bool {
  61. return lhs.index < rhs.index;
  62. }
  63. template <typename IndexType,
  64. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  65. nullptr>
  66. auto operator<=(IndexType lhs, IndexType rhs) -> bool {
  67. return lhs.index <= rhs.index;
  68. }
  69. template <typename IndexType,
  70. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  71. nullptr>
  72. auto operator>(IndexType lhs, IndexType rhs) -> bool {
  73. return lhs.index > rhs.index;
  74. }
  75. template <typename IndexType,
  76. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  77. nullptr>
  78. auto operator>=(IndexType lhs, IndexType rhs) -> bool {
  79. return lhs.index >= rhs.index;
  80. }
  81. // Provides base support for use of IdBase types as DenseMap/DenseSet keys.
  82. //
  83. // Usage (in global namespace):
  84. // template <>
  85. // struct llvm::DenseMapInfo<Carbon::MyType>
  86. // : public Carbon::IndexMapInfo<Carbon::MyType> {};
  87. template <typename Index>
  88. struct IndexMapInfo {
  89. static inline auto getEmptyKey() -> Index {
  90. return Index(llvm::DenseMapInfo<int32_t>::getEmptyKey());
  91. }
  92. static inline auto getTombstoneKey() -> Index {
  93. return Index(llvm::DenseMapInfo<int32_t>::getTombstoneKey());
  94. }
  95. static auto getHashValue(const Index& val) -> unsigned {
  96. return llvm::DenseMapInfo<int32_t>::getHashValue(val.index);
  97. }
  98. static auto isEqual(const Index& lhs, const Index& rhs) -> bool {
  99. return lhs == rhs;
  100. }
  101. };
  102. } // namespace Carbon
  103. #endif // CARBON_TOOLCHAIN_BASE_INDEX_BASE_H_