index_base.h 2.7 KB

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