Commit 9227a0f3 authored by Kenton Varda's avatar Kenton Varda

Eliminate RemoveReference -- all uses turned out to be unnecessary or outright wrong.

parent 2fc62718
......@@ -1431,13 +1431,13 @@ typeName DynamicValue::Builder::AsImpl<typeName>::apply(Builder& builder) { \
HANDLE_NUMERIC_TYPE(int8_t, checkRoundTrip, unsignedToSigned, checkRoundTrip)
HANDLE_NUMERIC_TYPE(int16_t, checkRoundTrip, unsignedToSigned, checkRoundTrip)
HANDLE_NUMERIC_TYPE(int32_t, checkRoundTrip, unsignedToSigned, checkRoundTrip)
HANDLE_NUMERIC_TYPE(int64_t, kj::upcast, unsignedToSigned, checkRoundTrip)
HANDLE_NUMERIC_TYPE(int64_t, kj::implicitCast, unsignedToSigned, checkRoundTrip)
HANDLE_NUMERIC_TYPE(uint8_t, signedToUnsigned, checkRoundTrip, checkRoundTrip)
HANDLE_NUMERIC_TYPE(uint16_t, signedToUnsigned, checkRoundTrip, checkRoundTrip)
HANDLE_NUMERIC_TYPE(uint32_t, signedToUnsigned, checkRoundTrip, checkRoundTrip)
HANDLE_NUMERIC_TYPE(uint64_t, signedToUnsigned, kj::upcast, checkRoundTrip)
HANDLE_NUMERIC_TYPE(float, kj::upcast, kj::upcast, kj::upcast)
HANDLE_NUMERIC_TYPE(double, kj::upcast, kj::upcast, kj::upcast)
HANDLE_NUMERIC_TYPE(uint64_t, signedToUnsigned, kj::implicitCast, checkRoundTrip)
HANDLE_NUMERIC_TYPE(float, kj::implicitCast, kj::implicitCast, kj::implicitCast)
HANDLE_NUMERIC_TYPE(double, kj::implicitCast, kj::implicitCast, kj::implicitCast)
#undef HANDLE_NUMERIC_TYPE
......
......@@ -743,7 +743,7 @@ BuilderFor<DynamicTypeFor<FromBuilder<T>>> toDynamic(T&& value) {
}
template <typename T>
DynamicTypeFor<TypeIfEnum<T>> toDynamic(T&& value) {
return DynamicEnum(Schema::from<kj::RemoveReference<T>>(), static_cast<uint16_t>(value));
return DynamicEnum(Schema::from<kj::Decay<T>>(), static_cast<uint16_t>(value));
}
inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {}
......
......@@ -63,18 +63,18 @@ using BuilderFor = typename internal::MaybeReaderBuilder<T>::Builder;
// The type returned by List<T>::Builder::operator[].
template <typename T>
using FromReader = typename kj::RemoveReference<T>::Reads;
using FromReader = typename kj::Decay<T>::Reads;
// FromReader<MyType::Reader> = MyType (for any Cap'n Proto type).
template <typename T>
using FromBuilder = typename kj::RemoveReference<T>::Builds;
using FromBuilder = typename kj::Decay<T>::Builds;
// FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type).
template <typename T, Kind k = kind<T>()> struct TypeIfEnum_;
template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
template <typename T>
using TypeIfEnum = typename TypeIfEnum_<kj::RemoveReference<T>>::Type;
using TypeIfEnum = typename TypeIfEnum_<kj::Decay<T>>::Type;
namespace internal {
......
......@@ -88,7 +88,7 @@ namespace {
template <typename List>
auto findSchemaMemberByName(const internal::RawSchema* raw, kj::StringPtr name,
uint unionIndex, List&& list)
-> kj::Maybe<kj::RemoveReference<decltype(list[0])>> {
-> kj::Maybe<kj::Decay<decltype(list[0])>> {
uint lower = 0;
uint upper = raw->memberCount;
......
......@@ -517,14 +517,14 @@ struct CopyConstructArray_<T, Iterator, false> {
static T* apply(T* __restrict__ pos, Iterator start, Iterator end) {
if (noexcept(T(instance<const T&>()))) {
while (start != end) {
ctor(*pos++, upcast<const T&>(*start++));
ctor(*pos++, implicitCast<const T&>(*start++));
}
return pos;
} else {
// Crap. This is complicated.
ExceptionGuard guard(pos);
while (start != end) {
ctor(*guard.pos, upcast<const T&>(*start++));
ctor(*guard.pos, implicitCast<const T&>(*start++));
++guard.pos;
}
guard.start = guard.pos;
......@@ -535,7 +535,7 @@ struct CopyConstructArray_<T, Iterator, false> {
template <typename T, typename Iterator>
inline T* copyConstructArray(T* dst, Iterator start, Iterator end) {
return CopyConstructArray_<T, RemoveReference<Iterator>>::apply(dst, start, end);
return CopyConstructArray_<T, Decay<Iterator>>::apply(dst, start, end);
}
} // namespace internal
......
......@@ -106,7 +106,7 @@ TEST(Common, Maybe) {
}
{
Maybe<int&> m = upcast<int*>(nullptr);
Maybe<int&> m = implicitCast<int*>(nullptr);
EXPECT_TRUE(m == nullptr);
EXPECT_FALSE(m != nullptr);
KJ_IF_MAYBE(v, m) {
......@@ -138,7 +138,7 @@ TEST(Common, Maybe) {
}
{
Maybe<int> m = upcast<int*>(nullptr);
Maybe<int> m = implicitCast<int*>(nullptr);
EXPECT_TRUE(m == nullptr);
EXPECT_FALSE(m != nullptr);
KJ_IF_MAYBE(v, m) {
......@@ -171,16 +171,23 @@ TEST(Common, MaybeConstness) {
class Foo {
public:
KJ_DISALLOW_COPY(Foo);
virtual ~Foo() {}
protected:
Foo() = default;
};
class Bar: public Foo {
public:
Bar() = default;
KJ_DISALLOW_COPY(Bar);
virtual ~Bar() {}
};
class Baz: public Foo {
public:
Baz() = delete;
KJ_DISALLOW_COPY(Baz);
virtual ~Baz() {}
};
......@@ -188,23 +195,21 @@ TEST(Common, Downcast) {
Bar bar;
Foo& foo = bar;
EXPECT_EQ(&bar, &downcast<Bar&>(foo));
EXPECT_EQ(&bar, downcast<Bar*>(&foo));
EXPECT_EQ(&bar, &downcast<Bar>(foo));
#if !defined(NDEBUG) && !KJ_NO_RTTI
EXPECT_ANY_THROW(downcast<Baz&>(foo));
EXPECT_ANY_THROW(downcast<Baz*>(&foo));
EXPECT_ANY_THROW(downcast<Baz>(foo));
#endif
#if KJ_NO_RTTI
EXPECT_TRUE(dynamicDowncastIfAvailable<Bar&>(foo) == nullptr);
EXPECT_TRUE(dynamicDowncastIfAvailable<Baz&>(foo) == nullptr);
#else
KJ_IF_MAYBE(m, dynamicDowncastIfAvailable<Bar&>(foo)) {
KJ_IF_MAYBE(m, dynamicDowncastIfAvailable<Bar>(foo)) {
EXPECT_EQ(&bar, m);
} else {
ADD_FAILURE() << "Dynamic downcast returned null.";
}
EXPECT_TRUE(dynamicDowncastIfAvailable<Baz&>(foo) == nullptr);
EXPECT_TRUE(dynamicDowncastIfAvailable<Baz>(foo) == nullptr);
#endif
}
......
......@@ -162,19 +162,10 @@ void inlineRequireFailure(
// =======================================================================================
// Template metaprogramming helpers.
template <typename T>
struct NoInfer_ {
// Use NoInfer<T>::Type in place of T for a template function parameter to prevent inference of
// the type based on the parameter value. There's something in the standard library for this but
// I didn't want to #include type_traits or whatever.
typedef T Type;
};
template <typename T>
using NoInfer = typename NoInfer_<T>::Type;
template <typename T> struct RemoveReference_ { typedef T Type; };
template <typename T> struct RemoveReference_<T&> { typedef T Type; };
template <typename T> using RemoveReference = typename RemoveReference_<T>::Type;
template <typename T> struct NoInfer_ { typedef T Type; };
template <typename T> using NoInfer = typename NoInfer_<T>::Type;
// Use NoInfer<T>::Type in place of T for a template function parameter to prevent inference of
// the type based on the parameter value.
template <typename T> struct RemoveConst_ { typedef T Type; };
template <typename T> struct RemoveConst_<const T> { typedef T Type; };
......@@ -265,15 +256,7 @@ template <typename T, typename U> using EnableIfDifferent = typename EnableIfDif
// when first encountered.
template<typename T> constexpr T&& mv(T& t) noexcept { return static_cast<T&&>(t); }
template<typename T>
constexpr T&& fwd(RemoveReference<T>& t) noexcept {
return static_cast<T&&>(t);
}
template<typename T> constexpr T&& fwd(RemoveReference<T>&& t) noexcept {
static_assert(!isLvalueReference<T>(), "Attempting to forward rvalue as lvalue reference.");
return static_cast<T&&>(t);
}
template<typename T> constexpr T&& fwd(NoInfer<T>& t) noexcept { return static_cast<T&&>(t); }
template <typename T, typename U>
auto min(T&& a, U&& b) -> decltype(a < b ? a : b) { return a < b ? a : b; }
......@@ -655,12 +638,12 @@ inline constexpr ArrayPtr<T> arrayPtr(T* begin, T* end) {
}
// =======================================================================================
// Upcast/downcast
// Casts
template <typename To, typename From>
To upcast(From&& from) {
// `upcast<T>(value)` casts `value` to type `T` only if the conversion is implicit. Useful for
// e.g. resolving ambiguous overloads without sacrificing type-safety.
To implicitCast(From&& from) {
// `implicitCast<T>(value)` casts `value` to type `T` only if the conversion is implicit. Useful
// for e.g. resolving ambiguous overloads without sacrificing type-safety.
return kj::fwd<From>(from);
}
......@@ -675,39 +658,32 @@ Maybe<To&> dynamicDowncastIfAvailable(From& from) {
// Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed
// we should have a separate cast function like dynamicCrosscastIfAvailable().
if (false) {
kj::upcast<From*>(upcast<RemoveReference<To>*>(nullptr));
kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr));
}
#if KJ_NO_RTTI
return nullptr;
#else
return dynamic_cast<RemoveReference<To>*>(&from);
return dynamic_cast<To*>(&from);
#endif
}
template <typename To, typename From>
To downcast(From* from) {
To& downcast(From& from) {
// Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a
// static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify
// that the value really has the requested type.
// Force a compile error if To is not a subtype of From.
if (false) {
kj::upcast<From*>(To());
kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr));
}
#if !KJ_NO_RTTI
KJ_IREQUIRE(from == nullptr || dynamic_cast<To>(from) != nullptr,
"Value cannot be downcast() to requested type.");
KJ_IREQUIRE(dynamic_cast<To*>(&from) != nullptr, "Value cannot be downcast() to requested type.");
#endif
return static_cast<To>(from);
}
template <typename To, typename From>
To downcast(From& from) {
// Reference version of downcast().
return *kj::downcast<RemoveReference<To>*>(&from);
return static_cast<To&>(from);
}
} // namespace kj
......
......@@ -55,7 +55,7 @@ public:
// Helper wrapper around disposeImpl().
//
// If T is polymorphic, calls `disposeImpl(dynamic_cast<void*>(object))`, otherwise calls
// `disposeImpl(upcast<void*>(object))`.
// `disposeImpl(implicitCast<void*>(object))`.
//
// Callers must not call dispose() on the same pointer twice, even if the first call throws
// an exception.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment