зеркало из https://github.com/mozilla/gecko-dev.git
Bug 766347 - Implement mozilla::IsConvertible to detect when a value of one type will convert to a value of another type. r=luke
--HG-- extra : rebase_source : d25c1b84dfc928a0bc4dcfb43e31b6035882849e
This commit is contained in:
Родитель
7eaf2877a0
Коммит
a10a240530
|
@ -27,8 +27,48 @@ class IsBaseOf
|
|||
private:
|
||||
static char test(Base* b);
|
||||
static int test(...);
|
||||
|
||||
public:
|
||||
static const bool value = (sizeof(test(static_cast<Derived*>(0))) == sizeof(char));
|
||||
static const bool value =
|
||||
sizeof(test(static_cast<Derived*>(0))) == sizeof(char);
|
||||
};
|
||||
|
||||
/*
|
||||
* IsConvertible determines whether a value of type From will implicitly convert
|
||||
* to a value of type To. For example:
|
||||
*
|
||||
* struct A {};
|
||||
* struct B : public A {};
|
||||
* struct C {};
|
||||
*
|
||||
* mozilla::IsConvertible<A, A>::value is true;
|
||||
* mozilla::IsConvertible<A*, A*>::value is true;
|
||||
* mozilla::IsConvertible<B, A>::value is true;
|
||||
* mozilla::IsConvertible<B*, A*>::value is true;
|
||||
* mozilla::IsConvertible<C, A>::value is false;
|
||||
* mozilla::IsConvertible<A, C>::value is false;
|
||||
* mozilla::IsConvertible<A*, C*>::value is false;
|
||||
* mozilla::IsConvertible<C*, A*>::value is false.
|
||||
*
|
||||
* For obscure reasons, you can't use IsConvertible when the types being tested
|
||||
* are related through private inheritance, and you'll get a compile error if
|
||||
* you try. Just don't do it!
|
||||
*/
|
||||
template<typename From, typename To>
|
||||
struct IsConvertible
|
||||
{
|
||||
private:
|
||||
static From create();
|
||||
|
||||
template<typename From1, typename To1>
|
||||
static char test(To to);
|
||||
|
||||
template<typename From1, typename To1>
|
||||
static int test(...);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test<From, To>(create())) == sizeof(char);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,7 @@ STL_FLAGS =
|
|||
|
||||
CPP_UNIT_TESTS = \
|
||||
TestCheckedInt.cpp \
|
||||
TestTypeTraits.cpp \
|
||||
$(NULL)
|
||||
|
||||
# in order to prevent rules.mk from trying to link to libraries that are
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
using mozilla::IsConvertible;
|
||||
|
||||
class A { };
|
||||
class B : public A { };
|
||||
class C : private A { };
|
||||
class D { };
|
||||
|
||||
static void
|
||||
TestIsConvertible()
|
||||
{
|
||||
// Pointer type convertibility
|
||||
MOZ_ASSERT((IsConvertible<A*, A*>::value),
|
||||
"A* should convert to A*");
|
||||
MOZ_ASSERT((IsConvertible<B*, A*>::value),
|
||||
"B* should convert to A*");
|
||||
MOZ_ASSERT((!IsConvertible<A*, B*>::value),
|
||||
"A* shouldn't convert to B*");
|
||||
MOZ_ASSERT((!IsConvertible<A*, C*>::value),
|
||||
"A* shouldn't convert to C*");
|
||||
MOZ_ASSERT((!IsConvertible<A*, D*>::value),
|
||||
"A* shouldn't convert to unrelated D*");
|
||||
MOZ_ASSERT((!IsConvertible<D*, A*>::value),
|
||||
"D* shouldn't convert to unrelated A*");
|
||||
|
||||
// Instance type convertibility
|
||||
MOZ_ASSERT((IsConvertible<A, A>::value),
|
||||
"A is A");
|
||||
MOZ_ASSERT((IsConvertible<B, A>::value),
|
||||
"B converts to A");
|
||||
MOZ_ASSERT((!IsConvertible<D, A>::value),
|
||||
"D and A are unrelated");
|
||||
MOZ_ASSERT((!IsConvertible<A, D>::value),
|
||||
"A and D are unrelated");
|
||||
|
||||
// These cases seem to require C++11 support to properly implement them, so
|
||||
// for now just disable them.
|
||||
//MOZ_ASSERT((!IsConvertible<C*, A*>::value),
|
||||
// "C* shouldn't convert to A* (private inheritance)");
|
||||
//MOZ_ASSERT((!IsConvertible<C, A>::value),
|
||||
// "C doesn't convert to A (private inheritance)");
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
TestIsConvertible();
|
||||
}
|
Загрузка…
Ссылка в новой задаче