ArchitectureSet.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //===- llvm/TextAPI/ArchitectureSet.h - ArchitectureSet ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Defines the architecture set.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURESET_H
  13. #define LLVM_TEXTAPI_MACHO_ARCHITECTURESET_H
  14. #include "llvm/TextAPI/Architecture.h"
  15. #include <cstddef>
  16. #include <iterator>
  17. #include <limits>
  18. #include <string>
  19. #include <tuple>
  20. #include <vector>
  21. namespace llvm {
  22. class raw_ostream;
  23. namespace MachO {
  24. class ArchitectureSet {
  25. private:
  26. using ArchSetType = uint32_t;
  27. const static ArchSetType EndIndexVal =
  28. std::numeric_limits<ArchSetType>::max();
  29. ArchSetType ArchSet{0};
  30. public:
  31. constexpr ArchitectureSet() = default;
  32. constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
  33. ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
  34. ArchitectureSet(const std::vector<Architecture> &Archs);
  35. void set(Architecture Arch) {
  36. if (Arch == AK_unknown)
  37. return;
  38. ArchSet |= 1U << static_cast<int>(Arch);
  39. }
  40. void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); }
  41. bool has(Architecture Arch) const {
  42. return ArchSet & (1U << static_cast<int>(Arch));
  43. }
  44. bool contains(ArchitectureSet Archs) const {
  45. return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
  46. }
  47. size_t count() const;
  48. bool empty() const { return ArchSet == 0; }
  49. ArchSetType rawValue() const { return ArchSet; }
  50. bool hasX86() const {
  51. return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
  52. }
  53. template <typename Ty> class arch_iterator {
  54. public:
  55. using iterator_category = std::forward_iterator_tag;
  56. using value_type = Architecture;
  57. using difference_type = std::size_t;
  58. using pointer = value_type *;
  59. using reference = value_type &;
  60. private:
  61. ArchSetType Index;
  62. Ty *ArchSet;
  63. void findNextSetBit() {
  64. if (Index == EndIndexVal)
  65. return;
  66. while (++Index < sizeof(Ty) * 8) {
  67. if (*ArchSet & (1UL << Index))
  68. return;
  69. }
  70. Index = EndIndexVal;
  71. }
  72. public:
  73. arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
  74. : Index(Index), ArchSet(ArchSet) {
  75. if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
  76. findNextSetBit();
  77. }
  78. Architecture operator*() const { return static_cast<Architecture>(Index); }
  79. arch_iterator &operator++() {
  80. findNextSetBit();
  81. return *this;
  82. }
  83. arch_iterator operator++(int) {
  84. auto tmp = *this;
  85. findNextSetBit();
  86. return tmp;
  87. }
  88. bool operator==(const arch_iterator &o) const {
  89. return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
  90. }
  91. bool operator!=(const arch_iterator &o) const { return !(*this == o); }
  92. };
  93. ArchitectureSet operator&(const ArchitectureSet &o) {
  94. return {ArchSet & o.ArchSet};
  95. }
  96. ArchitectureSet operator|(const ArchitectureSet &o) {
  97. return {ArchSet | o.ArchSet};
  98. }
  99. ArchitectureSet &operator|=(const ArchitectureSet &o) {
  100. ArchSet |= o.ArchSet;
  101. return *this;
  102. }
  103. ArchitectureSet &operator|=(const Architecture &Arch) {
  104. set(Arch);
  105. return *this;
  106. }
  107. bool operator==(const ArchitectureSet &o) const {
  108. return ArchSet == o.ArchSet;
  109. }
  110. bool operator!=(const ArchitectureSet &o) const {
  111. return ArchSet != o.ArchSet;
  112. }
  113. bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
  114. using iterator = arch_iterator<ArchSetType>;
  115. using const_iterator = arch_iterator<const ArchSetType>;
  116. iterator begin() { return {&ArchSet}; }
  117. iterator end() { return {&ArchSet, EndIndexVal}; }
  118. const_iterator begin() const { return {&ArchSet}; }
  119. const_iterator end() const { return {&ArchSet, EndIndexVal}; }
  120. operator std::string() const;
  121. operator std::vector<Architecture>() const;
  122. void print(raw_ostream &OS) const;
  123. };
  124. inline ArchitectureSet operator|(const Architecture &lhs,
  125. const Architecture &rhs) {
  126. return ArchitectureSet(lhs) | ArchitectureSet(rhs);
  127. }
  128. raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
  129. } // end namespace MachO.
  130. } // end namespace llvm.
  131. #endif // LLVM_TEXTAPI_MACHO_ARCHITECTURESET_H