mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
In the backdeploy library, `ActiveTaskStatus` takes `JobFlags::getPriority()` in the constexpr constructor; however, `JobFlags::getPriority()` isn't constexpr, so this is incorrect.
124 lines
4.4 KiB
C++
124 lines
4.4 KiB
C++
//===--- FlagSet.h - Helper class for opaque flag types ---------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the FlagSet template, a class which makes it easier to
|
|
// define opaque flag types.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_BASIC_FLAGSET_H
|
|
#define SWIFT_BASIC_FLAGSET_H
|
|
|
|
#include <type_traits>
|
|
#include <assert.h>
|
|
|
|
namespace swift {
|
|
|
|
/// A template designed to simplify the task of defining a wrapper type
|
|
/// for a flags bitfield.
|
|
///
|
|
/// Unfortunately, this doesn't currently support functional-style
|
|
/// building patterns, which means this can't practically be used for
|
|
/// types that need to be used in constant expressions.
|
|
template <typename IntType>
|
|
class FlagSet {
|
|
static_assert(std::is_integral<IntType>::value,
|
|
"storage type for FlagSet must be an integral type");
|
|
IntType Bits;
|
|
|
|
protected:
|
|
template <unsigned BitWidth>
|
|
static constexpr IntType lowMaskFor() {
|
|
return IntType((1 << BitWidth) - 1);
|
|
}
|
|
|
|
template <unsigned FirstBit, unsigned BitWidth = 1>
|
|
static constexpr IntType maskFor() {
|
|
return lowMaskFor<BitWidth>() << FirstBit;
|
|
}
|
|
|
|
constexpr FlagSet(IntType bits = 0) : Bits(bits) {}
|
|
|
|
/// Read a single-bit flag.
|
|
template <unsigned Bit>
|
|
bool getFlag() const {
|
|
return Bits & maskFor<Bit>();
|
|
}
|
|
|
|
/// Set a single-bit flag.
|
|
template <unsigned Bit>
|
|
void setFlag(bool value) {
|
|
if (value) {
|
|
Bits |= maskFor<Bit>();
|
|
} else {
|
|
Bits &= ~maskFor<Bit>();
|
|
}
|
|
}
|
|
|
|
/// Read a multi-bit field.
|
|
template <unsigned FirstBit, unsigned BitWidth, typename FieldType = IntType>
|
|
constexpr FieldType getField() const {
|
|
return FieldType((Bits >> FirstBit) & lowMaskFor<BitWidth>());
|
|
}
|
|
|
|
/// Assign to a multi-bit field.
|
|
template <unsigned FirstBit, unsigned BitWidth, typename FieldType = IntType>
|
|
void setField(typename std::enable_if<true, FieldType>::type value) {
|
|
// Note that we suppress template argument deduction for FieldType.
|
|
assert(IntType(value) <= lowMaskFor<BitWidth>() && "value out of range");
|
|
Bits = (Bits & ~maskFor<FirstBit, BitWidth>())
|
|
| (IntType(value) << FirstBit);
|
|
}
|
|
|
|
// A convenient macro for defining a getter and setter for a flag.
|
|
// Intended to be used in the body of a subclass of FlagSet.
|
|
#define FLAGSET_DEFINE_FLAG_ACCESSORS(BIT, GETTER, SETTER) \
|
|
bool GETTER() const { \
|
|
return this->template getFlag<BIT>(); \
|
|
} \
|
|
void SETTER(bool value) { \
|
|
this->template setFlag<BIT>(value); \
|
|
}
|
|
|
|
// A convenient macro for defining a getter and setter for a field.
|
|
// Intended to be used in the body of a subclass of FlagSet.
|
|
#define FLAGSET_DEFINE_FIELD_ACCESSORS(BIT, WIDTH, TYPE, GETTER, SETTER) \
|
|
constexpr TYPE GETTER() const { \
|
|
return this->template getField<BIT, WIDTH, TYPE>(); \
|
|
} \
|
|
void SETTER(TYPE value) { \
|
|
this->template setField<BIT, WIDTH, TYPE>(value); \
|
|
}
|
|
|
|
// A convenient macro to expose equality operators.
|
|
// These can't be provided directly by FlagSet because that would allow
|
|
// different flag sets to be compared if they happen to have the same
|
|
// underlying type.
|
|
#define FLAGSET_DEFINE_EQUALITY(TYPENAME) \
|
|
friend bool operator==(TYPENAME lhs, TYPENAME rhs) { \
|
|
return lhs.getOpaqueValue() == rhs.getOpaqueValue(); \
|
|
} \
|
|
friend bool operator!=(TYPENAME lhs, TYPENAME rhs) { \
|
|
return lhs.getOpaqueValue() != rhs.getOpaqueValue(); \
|
|
}
|
|
|
|
public:
|
|
/// Get the bits as an opaque integer value.
|
|
IntType getOpaqueValue() const {
|
|
return Bits;
|
|
}
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|