blob: d8dfc7f1af214aa98787a91118915d2d7128be07 [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===- llvm/TextAPI/MachO/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
13#ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
14#define LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
15
16#include "llvm/Support/raw_ostream.h"
17#include "llvm/TextAPI/MachO/Architecture.h"
18#include <cstddef>
19#include <iterator>
20#include <limits>
21#include <vector>
22
23namespace llvm {
24namespace MachO {
25
26class ArchitectureSet {
27private:
28 using ArchSetType = uint32_t;
29
30 const static ArchSetType EndIndexVal =
31 std::numeric_limits<ArchSetType>::max();
32 ArchSetType ArchSet{0};
33
34public:
35 constexpr ArchitectureSet() = default;
36 constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
37 ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
38 ArchitectureSet(const std::vector<Architecture> &Archs);
39
40 void set(Architecture Arch) {
41 if (Arch == AK_unknown)
42 return;
43 ArchSet |= 1U << static_cast<int>(Arch);
44 }
45
46 void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); }
47
48 bool has(Architecture Arch) const {
49 return ArchSet & (1U << static_cast<int>(Arch));
50 }
51
52 bool contains(ArchitectureSet Archs) const {
53 return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
54 }
55
56 size_t count() const;
57
58 bool empty() const { return ArchSet == 0; }
59
60 ArchSetType rawValue() const { return ArchSet; }
61
62 template <typename Ty>
63 class arch_iterator
64 : public std::iterator<std::forward_iterator_tag, Architecture, size_t> {
65 private:
66 ArchSetType Index;
67 Ty *ArchSet;
68
69 void findNextSetBit() {
70 if (Index == EndIndexVal)
71 return;
72 while (++Index < sizeof(Ty) * 8) {
73 if (*ArchSet & (1UL << Index))
74 return;
75 }
76
77 Index = EndIndexVal;
78 }
79
80 public:
81 arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
82 : Index(Index), ArchSet(ArchSet) {
83 if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
84 findNextSetBit();
85 }
86
87 Architecture operator*() const { return static_cast<Architecture>(Index); }
88
89 arch_iterator &operator++() {
90 findNextSetBit();
91 return *this;
92 }
93
94 arch_iterator operator++(int) {
95 auto tmp = *this;
96 findNextSetBit();
97 return tmp;
98 }
99
100 bool operator==(const arch_iterator &o) const {
101 return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
102 }
103
104 bool operator!=(const arch_iterator &o) const { return !(*this == o); }
105 };
106
107 ArchitectureSet operator&(const ArchitectureSet &o) {
108 return {ArchSet & o.ArchSet};
109 }
110
111 ArchitectureSet operator|(const ArchitectureSet &o) {
112 return {ArchSet | o.ArchSet};
113 }
114
115 ArchitectureSet &operator|=(const ArchitectureSet &o) {
116 ArchSet |= o.ArchSet;
117 return *this;
118 }
119
120 ArchitectureSet &operator|=(const Architecture &Arch) {
121 set(Arch);
122 return *this;
123 }
124
125 bool operator==(const ArchitectureSet &o) const {
126 return ArchSet == o.ArchSet;
127 }
128
129 bool operator!=(const ArchitectureSet &o) const {
130 return ArchSet != o.ArchSet;
131 }
132
133 bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
134
135 using iterator = arch_iterator<ArchSetType>;
136 using const_iterator = arch_iterator<const ArchSetType>;
137
138 iterator begin() { return {&ArchSet}; }
139 iterator end() { return {&ArchSet, EndIndexVal}; }
140
141 const_iterator begin() const { return {&ArchSet}; }
142 const_iterator end() const { return {&ArchSet, EndIndexVal}; }
143
144 operator std::string() const;
145 operator std::vector<Architecture>() const;
146 void print(raw_ostream &OS) const;
147};
148
149inline ArchitectureSet operator|(const Architecture &lhs,
150 const Architecture &rhs) {
151 return ArchitectureSet(lhs) | ArchitectureSet(rhs);
152}
153
154raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
155
156} // end namespace MachO.
157} // end namespace llvm.
158
159#endif // LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H