Files
swift-mirror/include/swift/Basic/FlagSet.h
John McCall 31f2eec044 Change type metadata accessors to support incomplete metadata.
This includes global generic and non-generic global access
functions, protocol associated type access functions,
swift_getGenericMetadata, and generic type completion functions.

The main part of this change is that the functions now need to take
a MetadataRequest and return a MetadataResponse, which is capable
of expressing that the request can fail.  The state of the returned
metadata is reported as an second, independent return value; this
allows the caller to easily check the possibility of failure without
having to mask it out from the returned metadata pointer, as well
as allowing it to be easily ignored.

Also, change metadata access functions to use swiftcc to ensure that
this return value is indeed returned in two separate registers.

Also, change protocol associated conformance access functions to use
swiftcc.  This isn't really related, but for some reason it snuck in.
Since it's clearly the right thing to do, and since I really didn't
want to retroactively tease that back out from all the rest of the
test changes, I've left it in.

Also, change generic metadata access functions to either pass all
the generic arguments directly or pass them all indirectly.  I don't
know how we ended up with the hybrid approach.  I needed to change all
the code-generation and calls here anyway in order to pass the request
parameter, and I figured I might as well change the ABI to something
sensible.
2018-03-18 21:38:08 -04:00

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>
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) \
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