index_base.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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_COMMON_INDEX_BASE_H_
  5. #define CARBON_TOOLCHAIN_COMMON_INDEX_BASE_H_
  6. #include <type_traits>
  7. #include "common/ostream.h"
  8. #include "llvm/ADT/SmallVector.h"
  9. #include "llvm/ADT/iterator.h"
  10. #include "llvm/Support/Format.h"
  11. namespace Carbon {
  12. template <typename DataType>
  13. class DataIterator;
  14. // A lightweight handle to an item in a vector.
  15. //
  16. // DataIndex is designed to be passed by value, not reference or pointer. They
  17. // are also designed to be small and efficient to store in data structures.
  18. struct IndexBase {
  19. static constexpr int32_t InvalidIndex = -1;
  20. IndexBase() = delete;
  21. constexpr explicit IndexBase(int index) : index(index) {}
  22. auto Print(llvm::raw_ostream& output) const -> void {
  23. if (is_valid()) {
  24. output << index;
  25. } else {
  26. output << "<invalid>";
  27. }
  28. }
  29. auto is_valid() const -> bool { return index != InvalidIndex; }
  30. int32_t index;
  31. };
  32. // Like IndexBase, but also provides < and > comparison operators.
  33. struct ComparableIndexBase : public IndexBase {
  34. using IndexBase::IndexBase;
  35. };
  36. // Equality comparison for both IndexBase and ComparableIndexBase.
  37. template <typename IndexType,
  38. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  39. nullptr>
  40. auto operator==(IndexType lhs, IndexType rhs) -> bool {
  41. return lhs.index == rhs.index;
  42. }
  43. template <typename IndexType,
  44. typename std::enable_if_t<std::is_base_of_v<IndexBase, IndexType>>* =
  45. nullptr>
  46. auto operator!=(IndexType lhs, IndexType rhs) -> bool {
  47. return lhs.index != rhs.index;
  48. }
  49. // The < and > comparisons for only ComparableIndexBase.
  50. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  51. ComparableIndexBase, IndexType>>* = nullptr>
  52. auto operator<(IndexType lhs, IndexType rhs) -> bool {
  53. return lhs.index < rhs.index;
  54. }
  55. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  56. ComparableIndexBase, IndexType>>* = nullptr>
  57. auto operator<=(IndexType lhs, IndexType rhs) -> bool {
  58. return lhs.index <= rhs.index;
  59. }
  60. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  61. ComparableIndexBase, IndexType>>* = nullptr>
  62. auto operator>(IndexType lhs, IndexType rhs) -> bool {
  63. return lhs.index > rhs.index;
  64. }
  65. template <typename IndexType, typename std::enable_if_t<std::is_base_of_v<
  66. ComparableIndexBase, IndexType>>* = nullptr>
  67. auto operator>=(IndexType lhs, IndexType rhs) -> bool {
  68. return lhs.index >= rhs.index;
  69. }
  70. } // namespace Carbon
  71. #endif // CARBON_TOOLCHAIN_COMMON_INDEX_BASE_H_