| //===- llvm/TextAPI/ArchitectureSet.h - ArchitectureSet ---------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Defines the architecture set. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_TEXTAPI_ARCHITECTURESET_H |
| #define LLVM_TEXTAPI_ARCHITECTURESET_H |
| |
| #include "llvm/TextAPI/Architecture.h" |
| #include <cstddef> |
| #include <iterator> |
| #include <limits> |
| #include <string> |
| #include <tuple> |
| #include <vector> |
| |
| namespace llvm { |
| class raw_ostream; |
| |
| namespace MachO { |
| |
| class ArchitectureSet { |
| private: |
| using ArchSetType = uint32_t; |
| |
| const static ArchSetType EndIndexVal = |
| std::numeric_limits<ArchSetType>::max(); |
| ArchSetType ArchSet{0}; |
| |
| public: |
| constexpr ArchitectureSet() = default; |
| constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {} |
| ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); } |
| ArchitectureSet(const std::vector<Architecture> &Archs); |
| |
| void set(Architecture Arch) { |
| if (Arch == AK_unknown) |
| return; |
| ArchSet |= 1U << static_cast<int>(Arch); |
| } |
| |
| void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); } |
| |
| bool has(Architecture Arch) const { |
| return ArchSet & (1U << static_cast<int>(Arch)); |
| } |
| |
| bool contains(ArchitectureSet Archs) const { |
| return (ArchSet & Archs.ArchSet) == Archs.ArchSet; |
| } |
| |
| size_t count() const; |
| |
| bool empty() const { return ArchSet == 0; } |
| |
| ArchSetType rawValue() const { return ArchSet; } |
| |
| bool hasX86() const { |
| return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h); |
| } |
| |
| template <typename Ty> class arch_iterator { |
| public: |
| using iterator_category = std::forward_iterator_tag; |
| using value_type = Architecture; |
| using difference_type = std::size_t; |
| using pointer = value_type *; |
| using reference = value_type &; |
| |
| private: |
| ArchSetType Index; |
| Ty *ArchSet; |
| |
| void findNextSetBit() { |
| if (Index == EndIndexVal) |
| return; |
| while (++Index < sizeof(Ty) * 8) { |
| if (*ArchSet & (1UL << Index)) |
| return; |
| } |
| |
| Index = EndIndexVal; |
| } |
| |
| public: |
| arch_iterator(Ty *ArchSet, ArchSetType Index = 0) |
| : Index(Index), ArchSet(ArchSet) { |
| if (Index != EndIndexVal && !(*ArchSet & (1UL << Index))) |
| findNextSetBit(); |
| } |
| |
| Architecture operator*() const { return static_cast<Architecture>(Index); } |
| |
| arch_iterator &operator++() { |
| findNextSetBit(); |
| return *this; |
| } |
| |
| arch_iterator operator++(int) { |
| auto tmp = *this; |
| findNextSetBit(); |
| return tmp; |
| } |
| |
| bool operator==(const arch_iterator &o) const { |
| return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet); |
| } |
| |
| bool operator!=(const arch_iterator &o) const { return !(*this == o); } |
| }; |
| |
| ArchitectureSet operator&(const ArchitectureSet &o) { |
| return {ArchSet & o.ArchSet}; |
| } |
| |
| ArchitectureSet operator|(const ArchitectureSet &o) { |
| return {ArchSet | o.ArchSet}; |
| } |
| |
| ArchitectureSet &operator|=(const ArchitectureSet &o) { |
| ArchSet |= o.ArchSet; |
| return *this; |
| } |
| |
| ArchitectureSet &operator|=(const Architecture &Arch) { |
| set(Arch); |
| return *this; |
| } |
| |
| bool operator==(const ArchitectureSet &o) const { |
| return ArchSet == o.ArchSet; |
| } |
| |
| bool operator!=(const ArchitectureSet &o) const { |
| return ArchSet != o.ArchSet; |
| } |
| |
| bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; } |
| |
| using iterator = arch_iterator<ArchSetType>; |
| using const_iterator = arch_iterator<const ArchSetType>; |
| |
| iterator begin() { return {&ArchSet}; } |
| iterator end() { return {&ArchSet, EndIndexVal}; } |
| |
| const_iterator begin() const { return {&ArchSet}; } |
| const_iterator end() const { return {&ArchSet, EndIndexVal}; } |
| |
| operator std::string() const; |
| operator std::vector<Architecture>() const; |
| void print(raw_ostream &OS) const; |
| }; |
| |
| inline ArchitectureSet operator|(const Architecture &lhs, |
| const Architecture &rhs) { |
| return ArchitectureSet(lhs) | ArchitectureSet(rhs); |
| } |
| |
| raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set); |
| |
| } // end namespace MachO. |
| } // end namespace llvm. |
| |
| #endif // LLVM_TEXTAPI_ARCHITECTURESET_H |