Bug 1041914 - Convert the fourth quarter of MFBT to Gecko style. r=Ms2ger.

--HG--
extra : rebase_source : 588fa9c0d1e819e1826835c4ef4a1428a927bf93
This commit is contained in:
Nicholas Nethercote 2014-07-22 20:54:41 -07:00
parent b232975926
commit 6c3f5d7b8e
28 changed files with 1648 additions and 1719 deletions

View File

@ -672,7 +672,7 @@ private:
#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \
template<typename T> \
inline CheckedInt<T> \
operator OP(const CheckedInt<T> &aLhs, const CheckedInt<T> &aRhs) \
operator OP(const CheckedInt<T>& aLhs, const CheckedInt<T>& aRhs) \
{ \
if (!detail::Is##NAME##Valid(aLhs.mValue, aRhs.mValue)) { \
return CheckedInt<T>(0, false); \
@ -732,12 +732,12 @@ castToCheckedInt(U aU)
return *this; \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(const CheckedInt<T> &aLhs, U aRhs) \
inline CheckedInt<T> operator OP(const CheckedInt<T>& aLhs, U aRhs) \
{ \
return aLhs OP castToCheckedInt<T>(aRhs); \
} \
template<typename T, typename U> \
inline CheckedInt<T> operator OP(U aLhs, const CheckedInt<T> &aRhs) \
inline CheckedInt<T> operator OP(U aLhs, const CheckedInt<T>& aRhs) \
{ \
return castToCheckedInt<T>(aLhs) OP aRhs; \
}
@ -752,14 +752,14 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=)
template<typename T, typename U>
inline bool
operator ==(const CheckedInt<T> &aLhs, U aRhs)
operator ==(const CheckedInt<T>& aLhs, U aRhs)
{
return aLhs == castToCheckedInt<T>(aRhs);
}
template<typename T, typename U>
inline bool
operator ==(U aLhs, const CheckedInt<T> &aRhs)
operator ==(U aLhs, const CheckedInt<T>& aRhs)
{
return castToCheckedInt<T>(aLhs) == aRhs;
}

View File

@ -40,8 +40,10 @@ extern "C" {
/* These definitions are usually provided through the
* sanitizer/asan_interface.h header installed by ASan.
*/
void MOZ_EXPORT __asan_poison_memory_region(void const volatile *addr, size_t size);
void MOZ_EXPORT __asan_unpoison_memory_region(void const volatile *addr, size_t size);
void MOZ_EXPORT
__asan_poison_memory_region(void const volatile *addr, size_t size);
void MOZ_EXPORT
__asan_unpoison_memory_region(void const volatile *addr, size_t size);
#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
__asan_poison_memory_region((addr), (size))

View File

@ -1,386 +1,11 @@
New files added to MFBT should follow standard Mozilla style, and existing
files are in the process of being converted. Nonetheless, some files still use
the old style, which is described below.
MFBT uses standard Mozilla style, with the following exceptions.
= mfbt style rules =
- Some of the files use a lower-case letter at the start of function names.
This is because MFBT used to use a different style, and was later converted
to standard Mozilla style. These functions have not been changed to use an
upper-case letter because it would cause a lot of churn in other parts of the
codebase. However, new files should follow standard Mozilla style and use an
upper-case letter at the start of function names.
== Line length ==
The line limit is 80 characters, except that excessively long blocks of
preprocessor directives may exceed this if it makes the code more readable (e.g.
MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g.
URLs) may exceed this as well. Wrap expressions after binary operators.
== Capitalization ==
Standalone functions, classes, structs, and template parameters are named
InterCaps-style. Member functions and fields in classes and structs are named
camelCaps-style.
== Indentation ==
Indentation is two spaces, never tabs.
if (x == 2)
return 17;
== Whitespace ==
Surround binary operators with a single space on either side.
if (x == 2)
return 17;
When describing pointer types, the * shall be adjacent to the type name. (Same
goes for references -- & goes by the type name.)
int
Foo(int* p)
{
typedef void* VoidPtr;
int& i = *p;
}
A corollary: don't mix declaration types by declaring a T and a T* (or a T**,
&c.) in the same declaration.
T* foo, bar; // BAD
== Expressions ==
Ternary expressions (a ? b : c) should use only one line if sufficiently short.
Longer ternary expressions should use multiple lines. The condition,
consequent, and alternative should each be on separate lines (each part
overflowing to additional lines as necessary), and the ? and : should be aligned
with the start of the condition:
size_t
BinaryTree::height()
{
return isLeaf()
? 0
: 1 + std::max(left()->height(),
right()->height());
}
== Bracing ==
Don't brace single statements.
if (y == 7)
return 3;
for (size_t i = 0; i < 5; i++)
frob(i);
But do brace them if the statement (or condition(s) or any additional
consequents, if the braces would be associated with an if statement) occupies
multiple lines.
if (cond1 ||
cond2)
{
action();
}
if (cond1) {
consequent();
} else {
alternative(arg1,
arg2);
}
if (cond1 || cond2) {
callMethod(arg1,
arg2);
}
for (size_t j = 0;
j < 17;
j++)
{
action();
}
Braces in control flow go at the end of the line except when associated with an
|if| or loop-head where the condition covers multiple lines
== Classes and structs ==
Inside class and structure definitions, public/private consume one level of
indentation.
class Baz
{
public:
Baz() { }
};
The absence of public/private in structs in which all members are public still
consumes a level.
struct Foo
{
int field;
};
Braces delimiting a class or struct go on their own lines.
Member initialization in constructors should be formatted as follows:
class Fnord
{
size_t s1, s2, s3, s4, s5;
public:
Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { }
Fnord()
: s1(0), /* member initialization can be compressed if desired */
s2(0),
s3(0),
s4(0),
s5(0)
{
...
}
};
Fields should go first in the class so that the basic structure is all in one
place, consistently.
Use the inline keyword to annotate functions defined inline in a header. (If
the function is defined inline in the class, don't bother adding it
redundantly.)
Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and
assignment operator from classes not intended to be copied or assigned to avoid
mistakes.
class Funky
{
public:
Funky() { }
private:
Funky(const Funky& other) MOZ_DELETE;
void operator=(const Funky& other) MOZ_DELETE;
};
Include a blank line between sections of structs and classes with different
access control.
The "get" prefix is used when a method is fallible. If it's infallible, don't
use it.
class String
{
public:
size_t length() const; // not getLength()
};
== Templates ==
Capitalize template parameter names to distinguish them from fields.
template<size_t KeySize, typename T>
class BloomFilter
{
};
Use single-letter names if it makes sense (T for an arbitrary type, K for key
type, V for value type, &c.). Otherwise use InterCaps-style names.
When declaring or defining a function, template<...> goes on one line, the
return type and other specifiers go on another line, and the function name and
argument list go on a third line.
template<typename T>
inline bool
Vector::add(T t)
{
}
== Namespaces ==
All C++ code shall be in the mozilla namespace, except that functionality only
used to implement external-facing API should be in the mozilla::detail
namespace, indicating that it should not be directly used.
Namespace opening braces go on the same line as the namespace declaration.
Namespace closing braces shall be commented. Namespace contents are not
indented.
namespace mozilla {
...
} // namespace mozilla
Don't use |using| in a header unless it's confined to a class or method.
Implementation files for out-of-line functionality may use |using|.
Name data structures and methods which must be usable in C code with a Moz*
prefix, e.g. MozCustomStructure. If the data structure is not meant to be used
outside of the header in which it is found (i.e. it would be in mozilla::detail
but for its being required to work in C code), add a corresponding comment to
highlight this.
== #includes ==
Headers that include mfbt headers use a fully-qualified include path, even if
full qualification is not strictly necessary.
#include "mozilla/Assertions.h"
mfbt headers should be included first, alphabetically. Standard includes should
follow, separated from mfbt includes by a blank line.
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include <string.h>
If a header dependency is limited simply to the existence of a class,
forward-declare it rather than #include that header.
namespace mozilla {
class BloomFilter;
extern bool
Test(BloomFilter* bf);
} // namespace mozilla
== Preprocessor ==
Include guards should be named by determining the fully-qualified include path,
and substituting _ for / and . in it. For example, "mozilla/Assertions.h"
becomes mozilla_Assertions_h.
Nested preprocessor directives indent the directive name (but not the #) by two
spaces.
#ifdef __clang__
# define FOO ...
#else
# define FOO ...
#endif
Comments within nested preprocessor directives align with directive names at
that nesting depth.
#if defined(__GNUC__)
/* gcc supports C++11 override syntax. */
# define MOZ_OVERRIDE override
#else
# define MOZ_OVERRIDE /* unsupported */
#endif
Feature-testing macros may be defined to nothing. Macros intended to be
textually expanded should be defined to a comment indicating non-support, as
above or as appropriate to the situation.
No particular preference is expressed between testing for a macro being defined
using defined(...) and using #ifdef.
When defining a macro with different expansions for different compilers, the top
level of distinction should be the compiler, and the next nested level should be
the compiler version. Clang seems likely to be around for awhile, so to reduce
confusion test for it separately from gcc even when it's not strictly necessary.
#if defined(__clang__)
#elif defined(__GNUC__)
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# else
# endif
#elif defined(_MSC_VER)
#endif
But don't distinguish clang's feature support using version checks: use the
__has_feature() and __has_extension() macros instead, because vendors may
customize clang's version numbers.
Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so
on) that are part of the mfbt interface. (C++ implementation files implementing
mfbt's interface but which are not directly part of that interface may ignore
this rule.)
Prefer inline functions to macros whenever possible.
== Comments ==
Header files shall have a short descriptive comment underneath license
boilerplate indicating what functionality the file implements, to be picked up
by MXR and displayed in directory listings. (But see bug 717196, which
currently prevents MXR from doing this if the MPL2 boilerplate is used.)
Assertions.h:
...license boilerplate...
/* Implementations of runtime and static assertion macros for C and C++. */
Classes intended for public use shall have interface comments explaining their
functionality from the user's perspective. These comments shall include
examples of how the relevant functionality might be used. These interface
comments use /** */ doxygen/Javadoc-style comments.
/**
* The Frobber class simplifies the process of frobbing.
*/
class Frobber
{
};
Comments describing implementation details (tradeoffs considered, assumptions
made, mathematical background, &c.) occur separately from interface comments so
that users need not consider them. They should go inside the class definition
or inside the appropriate method, depending on the specificity of the comment.
Headers which are intended to be C-compatible shall use only /**/-style
comments. (Code examples nested inside documentation comments may use //-style
comments.) Headers which are C++-compatible may also use //-style comments.
Non-interface comments that are /**/-style shall not also be doxygen-style.
Use Python-style ** to denote exponentiation inside comments, not ^ (which can
be confused with C-style bitwise xor). If you're writing sufficiently complex
math, feel free to descend into LaTeX math mode ;-) inside implementation
comments if you need to. (But keep it out of interface comments, because most
people probably haven't seen LaTeX.)
== Miscellaneous ==
Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the
block start/end as needed. The contents of these blocks should not be indented.
Add new functionality to new headers unless an existing header makes sense.
Err on the side of more headers rather than fewer, as this helps to minimize
dependencies.
Don't use bool for argument types unless the method is a "set" or "enable"-style
method where the method name and bool value together indicate the sense of its
effect. Use well-named enums in all other places, so that the semantics of the
argument are clear at a glance and do not require knowing how the method
interprets that argument.
void
setVisible(bool visible); // true clearly means visible, false clearly not
enum Enumerability {
Enumerable,
NonEnumerable
};
bool
DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e);
Use NULL for the null pointer constant.
If a consequent in an if-statement ends with a return, don't specify an else.
The else would be redundant with the return, and not using it avoids excess
indentation. If you feel the if-else alternation is important as a way to
think about the choice being made, consider a ternary expression instead.
// BAD
if (f())
return 2;
else
return 5;
// GOOD
if (f())
return 2;
return 5;
// GOOD
return f() ? 2 : 5
- Imported third-party code (such as decimal/*, double-conversion/*, and lz4*)
remains in its original style.

View File

@ -306,8 +306,9 @@ class UniquePtr
void reset(Pointer p = Pointer()) {
Pointer old = ptr();
ptr() = p;
if (old != nullptr)
if (old != nullptr) {
getDeleter()(old);
}
}
void swap(UniquePtr& other) {
@ -450,8 +451,9 @@ class UniquePtr<T[], D>
void reset(Pointer p = Pointer()) {
Pointer old = tuple.first();
tuple.first() = p;
if (old != nullptr)
if (old != nullptr) {
tuple.second()(old);
}
}
private:
@ -631,7 +633,8 @@ template<typename T, typename A1, typename A2, typename A3, typename A4>
typename detail::UniqueSelector<T>::SingleObject
MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4)
{
return UniquePtr<T>(new T(Forward<A1>(a1), Forward<A2>(a2), Forward<A3>(a3), Forward<A4>(a4)));
return UniquePtr<T>(new T(Forward<A1>(a1), Forward<A2>(a2), Forward<A3>(a3),
Forward<A4>(a4)));
}
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>

View File

@ -182,7 +182,7 @@ public:
private:
friend class SupportsWeakPtrBase<T, WeakReference>;
explicit WeakPtrBase(const RefPtr<WeakReference> &aOther) : mRef(aOther) {}
explicit WeakPtrBase(const RefPtr<WeakReference>& aOther) : mRef(aOther) {}
RefPtr<WeakReference> mRef;
};

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -79,7 +80,7 @@ TestIsInRangeVoid()
MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, uintBegin, uintEnd2));
}
struct Base { int x; };
struct Base { int mX; };
static void
TestIsInRangeClass()
@ -213,12 +214,17 @@ TestIsInRangeClassDerivedEmpty()
uintptr_t uderivedEmptyEnd = uintptr_t(derivedEmptyEnd);
uintptr_t uderivedEmptyEnd2 = uintptr_t(derivedEmptyEnd2);
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyBegin, uderivedEmptyBegin, uderivedEmptyEnd));
MOZ_RELEASE_ASSERT(!IsInRange(derivedEmptyEnd, uderivedEmptyBegin, uderivedEmptyEnd));
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyBegin, uderivedEmptyBegin,
uderivedEmptyEnd));
MOZ_RELEASE_ASSERT(!IsInRange(derivedEmptyEnd, uderivedEmptyBegin,
uderivedEmptyEnd));
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyBegin, uderivedEmptyBegin, uderivedEmptyEnd2));
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyEnd, uderivedEmptyBegin, uderivedEmptyEnd2));
MOZ_RELEASE_ASSERT(!IsInRange(derivedEmptyEnd2, uderivedEmptyBegin, uderivedEmptyEnd2));
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyBegin, uderivedEmptyBegin,
uderivedEmptyEnd2));
MOZ_RELEASE_ASSERT(IsInRange(derivedEmptyEnd, uderivedEmptyBegin,
uderivedEmptyEnd2));
MOZ_RELEASE_ASSERT(!IsInRange(derivedEmptyEnd2, uderivedEmptyBegin,
uderivedEmptyEnd2));
}
struct ExtraDerived : Base { int y; };
@ -293,7 +299,8 @@ TestIsInRangeClassExtraDerivedEmpty()
MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2));
}
int main()
int
main()
{
TestIsInRangeNonClass();
TestIsInRangeVoid();

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -13,69 +15,71 @@ using mozilla::Relaxed;
using mozilla::ReleaseAcquire;
using mozilla::SequentiallyConsistent;
#define A(a,b) MOZ_RELEASE_ASSERT(a,b)
template <typename T, MemoryOrdering Order>
static void
TestTypeWithOrdering()
{
Atomic<T, Order> atomic(5);
MOZ_RELEASE_ASSERT(atomic == 5, "Atomic variable did not initialize");
A(atomic == 5, "Atomic variable did not initialize");
// Test atomic increment
MOZ_RELEASE_ASSERT(++atomic == T(6), "Atomic increment did not work");
MOZ_RELEASE_ASSERT(atomic++ == T(6), "Atomic post-increment did not work");
MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic post-increment did not work");
A(++atomic == T(6), "Atomic increment did not work");
A(atomic++ == T(6), "Atomic post-increment did not work");
A(atomic == T(7), "Atomic post-increment did not work");
// Test atomic decrement
MOZ_RELEASE_ASSERT(--atomic == 6, "Atomic decrement did not work");
MOZ_RELEASE_ASSERT(atomic-- == 6, "Atomic post-decrement did not work");
MOZ_RELEASE_ASSERT(atomic == 5, "Atomic post-decrement did not work");
A(--atomic == 6, "Atomic decrement did not work");
A(atomic-- == 6, "Atomic post-decrement did not work");
A(atomic == 5, "Atomic post-decrement did not work");
// Test other arithmetic.
T result;
result = (atomic += T(5));
MOZ_RELEASE_ASSERT(atomic == T(10), "Atomic += did not work");
MOZ_RELEASE_ASSERT(result == T(10), "Atomic += returned the wrong value");
A(atomic == T(10), "Atomic += did not work");
A(result == T(10), "Atomic += returned the wrong value");
result = (atomic -= T(3));
MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic -= did not work");
MOZ_RELEASE_ASSERT(result == T(7), "Atomic -= returned the wrong value");
A(atomic == T(7), "Atomic -= did not work");
A(result == T(7), "Atomic -= returned the wrong value");
// Test assignment
result = (atomic = T(5));
MOZ_RELEASE_ASSERT(atomic == T(5), "Atomic assignment failed");
MOZ_RELEASE_ASSERT(result == T(5), "Atomic assignment returned the wrong value");
A(atomic == T(5), "Atomic assignment failed");
A(result == T(5), "Atomic assignment returned the wrong value");
// Test logical operations.
result = (atomic ^= T(2));
MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic ^= did not work");
MOZ_RELEASE_ASSERT(result == T(7), "Atomic ^= returned the wrong value");
A(atomic == T(7), "Atomic ^= did not work");
A(result == T(7), "Atomic ^= returned the wrong value");
result = (atomic ^= T(4));
MOZ_RELEASE_ASSERT(atomic == T(3), "Atomic ^= did not work");
MOZ_RELEASE_ASSERT(result == T(3), "Atomic ^= returned the wrong value");
A(atomic == T(3), "Atomic ^= did not work");
A(result == T(3), "Atomic ^= returned the wrong value");
result = (atomic |= T(8));
MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
A(atomic == T(11), "Atomic |= did not work");
A(result == T(11), "Atomic |= returned the wrong value");
result = (atomic |= T(8));
MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
A(atomic == T(11), "Atomic |= did not work");
A(result == T(11), "Atomic |= returned the wrong value");
result = (atomic &= T(12));
MOZ_RELEASE_ASSERT(atomic == T(8), "Atomic &= did not work");
MOZ_RELEASE_ASSERT(result == T(8), "Atomic &= returned the wrong value");
A(atomic == T(8), "Atomic &= did not work");
A(result == T(8), "Atomic &= returned the wrong value");
// Test exchange.
atomic = T(30);
result = atomic.exchange(42);
MOZ_RELEASE_ASSERT(atomic == T(42), "Atomic exchange did not work");
MOZ_RELEASE_ASSERT(result == T(30), "Atomic exchange returned the wrong value");
A(atomic == T(42), "Atomic exchange did not work");
A(result == T(30), "Atomic exchange returned the wrong value");
// Test CAS.
atomic = T(1);
bool boolResult = atomic.compareExchange(0, 2);
MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
MOZ_RELEASE_ASSERT(atomic == T(1), "CAS shouldn't have done anything.");
A(!boolResult, "CAS should have returned false.");
A(atomic == T(1), "CAS shouldn't have done anything.");
boolResult = atomic.compareExchange(1, 42);
MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
MOZ_RELEASE_ASSERT(atomic == T(42), "CAS should have changed atomic's value.");
A(boolResult, "CAS should have succeeded.");
A(atomic == T(42), "CAS should have changed atomic's value.");
}
template<typename T, MemoryOrdering Order>
@ -84,49 +88,50 @@ TestPointerWithOrdering()
{
T array1[10];
Atomic<T*, Order> atomic(array1);
MOZ_RELEASE_ASSERT(atomic == array1, "Atomic variable did not initialize");
A(atomic == array1, "Atomic variable did not initialize");
// Test atomic increment
MOZ_RELEASE_ASSERT(++atomic == array1 + 1, "Atomic increment did not work");
MOZ_RELEASE_ASSERT(atomic++ == array1 + 1, "Atomic post-increment did not work");
MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic post-increment did not work");
A(++atomic == array1 + 1, "Atomic increment did not work");
A(atomic++ == array1 + 1, "Atomic post-increment did not work");
A(atomic == array1 + 2, "Atomic post-increment did not work");
// Test atomic decrement
MOZ_RELEASE_ASSERT(--atomic == array1 + 1, "Atomic decrement did not work");
MOZ_RELEASE_ASSERT(atomic-- == array1 + 1, "Atomic post-decrement did not work");
MOZ_RELEASE_ASSERT(atomic == array1, "Atomic post-decrement did not work");
A(--atomic == array1 + 1, "Atomic decrement did not work");
A(atomic-- == array1 + 1, "Atomic post-decrement did not work");
A(atomic == array1, "Atomic post-decrement did not work");
// Test other arithmetic operations
T* result;
result = (atomic += 2);
MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic += did not work");
MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic += returned the wrong value");
A(atomic == array1 + 2, "Atomic += did not work");
A(result == array1 + 2, "Atomic += returned the wrong value");
result = (atomic -= 1);
MOZ_RELEASE_ASSERT(atomic == array1 + 1, "Atomic -= did not work");
MOZ_RELEASE_ASSERT(result == array1 + 1, "Atomic -= returned the wrong value");
A(atomic == array1 + 1, "Atomic -= did not work");
A(result == array1 + 1, "Atomic -= returned the wrong value");
// Test stores
result = (atomic = array1);
MOZ_RELEASE_ASSERT(atomic == array1, "Atomic assignment did not work");
MOZ_RELEASE_ASSERT(result == array1, "Atomic assignment returned the wrong value");
A(atomic == array1, "Atomic assignment did not work");
A(result == array1, "Atomic assignment returned the wrong value");
// Test exchange
atomic = array1 + 2;
result = atomic.exchange(array1);
MOZ_RELEASE_ASSERT(atomic == array1, "Atomic exchange did not work");
MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic exchange returned the wrong value");
A(atomic == array1, "Atomic exchange did not work");
A(result == array1 + 2, "Atomic exchange returned the wrong value");
atomic = array1;
bool boolResult = atomic.compareExchange(array1 + 1, array1 + 2);
MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
MOZ_RELEASE_ASSERT(atomic == array1, "CAS shouldn't have done anything.");
A(!boolResult, "CAS should have returned false.");
A(atomic == array1, "CAS shouldn't have done anything.");
boolResult = atomic.compareExchange(array1, array1 + 3);
MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
MOZ_RELEASE_ASSERT(atomic == array1 + 3, "CAS should have changed atomic's value.");
A(boolResult, "CAS should have succeeded.");
A(atomic == array1 + 3, "CAS should have changed atomic's value.");
}
enum EnumType {
enum EnumType
{
EnumType_0 = 0,
EnumType_1 = 1,
EnumType_2 = 2,
@ -138,29 +143,29 @@ static void
TestEnumWithOrdering()
{
Atomic<EnumType, Order> atomic(EnumType_2);
MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic variable did not initialize");
A(atomic == EnumType_2, "Atomic variable did not initialize");
// Test assignment
EnumType result;
result = (atomic = EnumType_3);
MOZ_RELEASE_ASSERT(atomic == EnumType_3, "Atomic assignment failed");
MOZ_RELEASE_ASSERT(result == EnumType_3, "Atomic assignment returned the wrong value");
A(atomic == EnumType_3, "Atomic assignment failed");
A(result == EnumType_3, "Atomic assignment returned the wrong value");
// Test exchange.
atomic = EnumType_1;
result = atomic.exchange(EnumType_2);
MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic exchange did not work");
MOZ_RELEASE_ASSERT(result == EnumType_1, "Atomic exchange returned the wrong value");
A(atomic == EnumType_2, "Atomic exchange did not work");
A(result == EnumType_1, "Atomic exchange returned the wrong value");
// Test CAS.
atomic = EnumType_1;
bool boolResult = atomic.compareExchange(EnumType_0, EnumType_2);
MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
MOZ_RELEASE_ASSERT(atomic == EnumType_1, "CAS shouldn't have done anything.");
A(!boolResult, "CAS should have returned false.");
A(atomic == EnumType_1, "CAS shouldn't have done anything.");
boolResult = atomic.compareExchange(EnumType_1, EnumType_3);
MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
MOZ_RELEASE_ASSERT(atomic == EnumType_3, "CAS should have changed atomic's value.");
A(boolResult, "CAS should have succeeded.");
A(atomic == EnumType_3, "CAS should have changed atomic's value.");
}
template <MemoryOrdering Order>
@ -168,29 +173,29 @@ static void
TestBoolWithOrdering()
{
Atomic<bool, Order> atomic(false);
MOZ_RELEASE_ASSERT(atomic == false, "Atomic variable did not initialize");
A(atomic == false, "Atomic variable did not initialize");
// Test assignment
bool result;
result = (atomic = true);
MOZ_RELEASE_ASSERT(atomic == true, "Atomic assignment failed");
MOZ_RELEASE_ASSERT(result == true, "Atomic assignment returned the wrong value");
A(atomic == true, "Atomic assignment failed");
A(result == true, "Atomic assignment returned the wrong value");
// Test exchange.
atomic = false;
result = atomic.exchange(true);
MOZ_RELEASE_ASSERT(atomic == true, "Atomic exchange did not work");
MOZ_RELEASE_ASSERT(result == false, "Atomic exchange returned the wrong value");
A(atomic == true, "Atomic exchange did not work");
A(result == false, "Atomic exchange returned the wrong value");
// Test CAS.
atomic = false;
bool boolResult = atomic.compareExchange(true, false);
MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
MOZ_RELEASE_ASSERT(atomic == false, "CAS shouldn't have done anything.");
A(!boolResult, "CAS should have returned false.");
A(atomic == false, "CAS shouldn't have done anything.");
boolResult = atomic.compareExchange(false, true);
MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
MOZ_RELEASE_ASSERT(atomic == true, "CAS should have changed atomic's value.");
A(boolResult, "CAS should have succeeded.");
A(atomic == true, "CAS should have changed atomic's value.");
}
template <typename T>
@ -227,7 +232,10 @@ TestBool()
TestBoolWithOrdering<Relaxed>();
}
int main()
#undef A
int
main()
{
TestType<uint32_t>();
TestType<int32_t>();
@ -239,4 +247,5 @@ int main()
TestPointer<uint32_t*>();
TestEnum();
TestBool();
return 0;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -12,19 +13,20 @@ using mozilla::BinarySearch;
struct Person
{
int age;
int id;
Person(int age, int id) : age(age), id(id) {}
int mAge;
int mId;
Person(int aAge, int aId) : mAge(aAge), mId(aId) {}
};
struct GetAge
{
Vector<Person> &v;
explicit GetAge(Vector<Person> &v) : v(v) {}
int operator[](size_t index) const { return v[index].age; }
Vector<Person>& mV;
explicit GetAge(Vector<Person>& aV) : mV(aV) {}
int operator[](size_t index) const { return mV[index].mAge; }
};
int main()
int
main()
{
size_t m;
@ -66,11 +68,13 @@ int main()
v3.append(Person(4, 13));
v3.append(Person(6, 360));
MOZ_RELEASE_ASSERT(!BinarySearch(GetAge(v3), 0, v3.length(), 1, &m) && m == 0);
MOZ_RELEASE_ASSERT( BinarySearch(GetAge(v3), 0, v3.length(), 2, &m) && m == 0);
MOZ_RELEASE_ASSERT(!BinarySearch(GetAge(v3), 0, v3.length(), 3, &m) && m == 1);
MOZ_RELEASE_ASSERT( BinarySearch(GetAge(v3), 0, v3.length(), 4, &m) && m == 1);
MOZ_RELEASE_ASSERT(!BinarySearch(GetAge(v3), 0, v3.length(), 5, &m) && m == 2);
MOZ_RELEASE_ASSERT( BinarySearch(GetAge(v3), 0, v3.length(), 6, &m) && m == 2);
MOZ_RELEASE_ASSERT(!BinarySearch(GetAge(v3), 0, v3.length(), 7, &m) && m == 3);
#define A(a) MOZ_RELEASE_ASSERT(a)
A(!BinarySearch(GetAge(v3), 0, v3.length(), 1, &m) && m == 0);
A( BinarySearch(GetAge(v3), 0, v3.length(), 2, &m) && m == 0);
A(!BinarySearch(GetAge(v3), 0, v3.length(), 3, &m) && m == 1);
A( BinarySearch(GetAge(v3), 0, v3.length(), 4, &m) && m == 1);
A(!BinarySearch(GetAge(v3), 0, v3.length(), 5, &m) && m == 2);
A( BinarySearch(GetAge(v3), 0, v3.length(), 6, &m) && m == 2);
A(!BinarySearch(GetAge(v3), 0, v3.length(), 7, &m) && m == 3);
return 0;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -13,19 +14,19 @@ using mozilla::BloomFilter;
class FilterChecker
{
public:
explicit FilterChecker(uint32_t hash) : mHash(hash) { }
public:
explicit FilterChecker(uint32_t aHash) : mHash(aHash) { }
uint32_t hash() const { return mHash; }
uint32_t hash() const { return mHash; }
private:
uint32_t mHash;
private:
uint32_t mHash;
};
int
main()
{
BloomFilter<12, FilterChecker> *filter = new BloomFilter<12, FilterChecker>();
BloomFilter<12, FilterChecker>* filter = new BloomFilter<12, FilterChecker>();
MOZ_RELEASE_ASSERT(filter);
FilterChecker one(1);
@ -55,31 +56,31 @@ main()
// Test multiple addition/removal
const size_t FILTER_SIZE = 255;
for (size_t i = 0; i < FILTER_SIZE - 1; ++i)
for (size_t i = 0; i < FILTER_SIZE - 1; ++i) {
filter->add(&two);
}
MOZ_RELEASE_ASSERT(filter->mightContain(&multiple),
"Filter should contain 'multiple' after 'two' added lots of times "
"(false positive)");
for (size_t i = 0; i < FILTER_SIZE - 1; ++i)
for (size_t i = 0; i < FILTER_SIZE - 1; ++i) {
filter->remove(&two);
}
MOZ_RELEASE_ASSERT(!filter->mightContain(&multiple),
"Filter claims to contain 'multiple' when it should not after two "
"was removed lots of times");
// Test overflowing the filter buckets
for (size_t i = 0; i < FILTER_SIZE + 1; ++i)
for (size_t i = 0; i < FILTER_SIZE + 1; ++i) {
filter->add(&two);
}
MOZ_RELEASE_ASSERT(filter->mightContain(&multiple),
"Filter should contain 'multiple' after 'two' added lots more "
"times (false positive)");
for (size_t i = 0; i < FILTER_SIZE + 1; ++i)
for (size_t i = 0; i < FILTER_SIZE + 1; ++i) {
filter->remove(&two);
}
MOZ_RELEASE_ASSERT(filter->mightContain(&multiple),
"Filter claims to not contain 'multiple' even though we should "
"have run out of space in the buckets (false positive)");

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -16,15 +17,16 @@ struct UintUlongBitwiseCast;
template<typename Uint, typename Ulong>
struct UintUlongBitwiseCast<Uint, Ulong, true>
{
static void test() {
MOZ_RELEASE_ASSERT(BitwiseCast<Ulong>(Uint(8675309)) == Ulong(8675309));
}
static void test()
{
MOZ_RELEASE_ASSERT(BitwiseCast<Ulong>(Uint(8675309)) == Ulong(8675309));
}
};
template<typename Uint, typename Ulong>
struct UintUlongBitwiseCast<Uint, Ulong, false>
{
static void test() { }
static void test() { }
};
static void
@ -105,4 +107,6 @@ main()
TestSameSize();
TestToBiggerSize();
TestToSmallerSize();
return 0;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -12,39 +13,41 @@ using mozilla::RoundUpPow2;
static void
TestCeiling()
{
for (uint32_t i = 0; i <= 1; i++)
for (uint32_t i = 0; i <= 1; i++) {
MOZ_RELEASE_ASSERT(CeilingLog2(i) == 0);
for (uint32_t i = 2; i <= 2; i++)
}
for (uint32_t i = 2; i <= 2; i++) {
MOZ_RELEASE_ASSERT(CeilingLog2(i) == 1);
for (uint32_t i = 3; i <= 4; i++)
}
for (uint32_t i = 3; i <= 4; i++) {
MOZ_RELEASE_ASSERT(CeilingLog2(i) == 2);
for (uint32_t i = 5; i <= 8; i++)
}
for (uint32_t i = 5; i <= 8; i++) {
MOZ_RELEASE_ASSERT(CeilingLog2(i) == 3);
for (uint32_t i = 9; i <= 16; i++)
}
for (uint32_t i = 9; i <= 16; i++) {
MOZ_RELEASE_ASSERT(CeilingLog2(i) == 4);
}
}
static void
TestFloor()
{
for (uint32_t i = 0; i <= 1; i++)
for (uint32_t i = 0; i <= 1; i++) {
MOZ_RELEASE_ASSERT(FloorLog2(i) == 0);
for (uint32_t i = 2; i <= 3; i++)
}
for (uint32_t i = 2; i <= 3; i++) {
MOZ_RELEASE_ASSERT(FloorLog2(i) == 1);
for (uint32_t i = 4; i <= 7; i++)
}
for (uint32_t i = 4; i <= 7; i++) {
MOZ_RELEASE_ASSERT(FloorLog2(i) == 2);
for (uint32_t i = 8; i <= 15; i++)
}
for (uint32_t i = 8; i <= 15; i++) {
MOZ_RELEASE_ASSERT(FloorLog2(i) == 3);
for (uint32_t i = 16; i <= 31; i++)
}
for (uint32_t i = 16; i <= 31; i++) {
MOZ_RELEASE_ASSERT(FloorLog2(i) == 4);
}
}
static void
@ -75,7 +78,8 @@ TestRoundUpPow2()
// not valid to round up when past the max power of two
}
int main()
int
main()
{
TestCeiling();
TestFloor();

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -14,21 +15,22 @@ int gIntegerTypesTested = 0;
int gTestsPassed = 0;
int gTestsFailed = 0;
void verifyImplFunction(bool x, bool expected,
const char* file, int line,
int size, bool isTSigned)
void verifyImplFunction(bool aX, bool aExpected,
const char* aFile, int aLine,
int aSize, bool aIsTSigned)
{
if (x == expected) {
if (aX == aExpected) {
gTestsPassed++;
} else {
gTestsFailed++;
std::cerr << "Test failed at " << file << ":" << line;
std::cerr << "Test failed at " << aFile << ":" << aLine;
std::cerr << " with T a ";
if (isTSigned)
if (aIsTSigned) {
std::cerr << "signed";
else
} else {
std::cerr << "unsigned";
std::cerr << " " << CHAR_BIT*size << "-bit integer type" << std::endl;
}
std::cerr << " " << CHAR_BIT * aSize << "-bit integer type" << std::endl;
}
}
@ -49,25 +51,24 @@ void verifyImplFunction(bool x, bool expected,
template<typename T, size_t Size = sizeof(T)>
struct testTwiceBiggerType
{
static void run()
{
VERIFY(detail::IsSupported<typename detail::TwiceBiggerType<T>::Type>::value);
VERIFY(sizeof(typename detail::TwiceBiggerType<T>::Type)
== 2 * sizeof(T));
VERIFY(bool(IsSigned<typename detail::TwiceBiggerType<T>::Type>::value)
== bool(IsSigned<T>::value));
}
static void run()
{
VERIFY(detail::IsSupported<typename detail::TwiceBiggerType<T>::Type>::value);
VERIFY(sizeof(typename detail::TwiceBiggerType<T>::Type) == 2 * sizeof(T));
VERIFY(bool(IsSigned<typename detail::TwiceBiggerType<T>::Type>::value) ==
bool(IsSigned<T>::value));
}
};
template<typename T>
struct testTwiceBiggerType<T, 8>
{
static void run()
{
VERIFY_IS_FALSE(detail::IsSupported<
typename detail::TwiceBiggerType<T>::Type
>::value);
}
static void run()
{
VERIFY_IS_FALSE(detail::IsSupported<
typename detail::TwiceBiggerType<T>::Type
>::value);
}
};
@ -75,10 +76,12 @@ template<typename T>
void test()
{
static bool alreadyRun = false;
// Integer types from different families may just be typedefs for types from other families.
// e.g. int32_t might be just a typedef for int. No point re-running the same tests then.
if (alreadyRun)
return;
// Integer types from different families may just be typedefs for types from
// other families. E.g. int32_t might be just a typedef for int. No point
// re-running the same tests then.
if (alreadyRun) {
return;
}
alreadyRun = true;
VERIFY(detail::IsSupported<T>::value);
@ -95,14 +98,14 @@ void test()
const CheckedInt<T> max(MaxValue<T>::value);
const CheckedInt<T> min(MinValue<T>::value);
// Check MinValue and MaxValue, since they are custom implementations and a mistake there
// could potentially NOT be caught by any other tests... while making everything wrong!
// Check MinValue and MaxValue, since they are custom implementations and a
// mistake there could potentially NOT be caught by any other tests... while
// making everything wrong!
unsignedT bit = 1;
unsignedT unsignedMinValue(min.value());
unsignedT unsignedMaxValue(max.value());
for (size_t i = 0; i < sizeof(T) * CHAR_BIT - 1; i++)
{
for (size_t i = 0; i < sizeof(T) * CHAR_BIT - 1; i++) {
VERIFY((unsignedMinValue & bit) == 0);
bit <<= 1;
}
@ -119,7 +122,7 @@ void test()
VERIFY_IS_VALID(zero + zero);
VERIFY(zero + zero == zero);
VERIFY_IS_FALSE(zero + zero == one); // Check that == doesn't always return true
VERIFY_IS_FALSE(zero + zero == one); // Check == doesn't always return true
VERIFY_IS_VALID(zero + one);
VERIFY(zero + one == one);
VERIFY_IS_VALID(one + one);
@ -373,7 +376,8 @@ void test()
VERIFY_IS_INVALID(someInvalid / someInvalid);
VERIFY_IS_INVALID(someInvalid % someInvalid);
/* Check that mixing checked integers with plain integers in expressions is allowed */
// Check that mixing checked integers with plain integers in expressions is
// allowed
VERIFY(one + T(2) == three);
VERIFY(2 + one == three);
@ -438,8 +442,8 @@ void test()
VERIFY_IS_INVALID(foo);
}
// Check that construction of CheckedInt from an integer value of a mismatched type is checked
// Also check casting between all types.
// Check that construction of CheckedInt from an integer value of a
// mismatched type is checked Also check casting between all types.
#define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,V,PostVExpr) \
{ \
@ -447,10 +451,12 @@ void test()
VERIFY_IS_VALID(CheckedInt<T>(V( 0)PostVExpr)); \
VERIFY_IS_VALID(CheckedInt<T>(V( 1)PostVExpr)); \
VERIFY_IS_VALID(CheckedInt<T>(V(100)PostVExpr)); \
if (isUSigned) \
if (isUSigned) { \
VERIFY_IS_VALID_IF(CheckedInt<T>(V(-1)PostVExpr), isTSigned); \
if (sizeof(U) > sizeof(T)) \
} \
if (sizeof(U) > sizeof(T)) { \
VERIFY_IS_INVALID(CheckedInt<T>(V(MaxValue<T>::value)PostVExpr + one.value())); \
} \
VERIFY_IS_VALID_IF(CheckedInt<T>(MaxValue<U>::value), \
(sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \
VERIFY_IS_VALID_IF(CheckedInt<T>(MinValue<U>::value), \
@ -522,7 +528,8 @@ void test()
gIntegerTypesTested++;
}
int main()
int
main()
{
test<int8_t>();
test<uint8_t>();

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -25,7 +26,8 @@ TestCountPopulation32()
MOZ_RELEASE_ASSERT(CountPopulation32(0x00000000) == 0);
}
int main()
int
main()
{
TestCountPopulation32();
return 0;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -90,7 +91,8 @@ TestTrailingZeroes64()
MOZ_RELEASE_ASSERT(CountTrailingZeroes64(0x8000000000000000) == 63);
}
int main()
int
main()
{
TestLeadingZeroes32();
TestLeadingZeroes64();

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -13,31 +15,37 @@ using mozilla::NativeEndian;
template<typename T>
void
TestSingleSwap(T value, T swappedValue)
TestSingleSwap(T aValue, T aSwappedValue)
{
#if MOZ_LITTLE_ENDIAN
MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == aSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) == aSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) ==
aSwappedValue);
#else
MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(value) == swappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) == aSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) ==
aSwappedValue);
#endif
}
template<typename T>
void
TestSingleNoSwap(T value, T notSwappedValue)
TestSingleNoSwap(T aValue, T aUnswappedValue)
{
#if MOZ_LITTLE_ENDIAN
MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToLittleEndian(aValue) ==
aUnswappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromLittleEndian(aValue) ==
aUnswappedValue);
#else
MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(value) == notSwappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToBigEndian(aValue) == aUnswappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromBigEndian(aValue) == aUnswappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapToNetworkOrder(aValue) ==
aUnswappedValue);
MOZ_RELEASE_ASSERT(NativeEndian::swapFromNetworkOrder(aValue) ==
aUnswappedValue);
#endif
}
@ -51,9 +59,9 @@ TestSingleNoSwap(T value, T notSwappedValue)
#define WRAP_COPYTO(NAME) \
template<typename T> \
void \
NAME(void* dst, const T* src, size_t count) \
NAME(void* aDst, const T* aSrc, size_t aCount) \
{ \
NativeEndian::NAME<T>(dst, src, count); \
NativeEndian::NAME<T>(aDst, aSrc, aCount); \
}
WRAP_COPYTO(copyAndSwapToLittleEndian)
@ -63,9 +71,9 @@ WRAP_COPYTO(copyAndSwapToNetworkOrder)
#define WRAP_COPYFROM(NAME) \
template<typename T> \
void \
NAME(T* dst, const void* src, size_t count) \
NAME(T* aDst, const void* aSrc, size_t aCount) \
{ \
NativeEndian::NAME<T>(dst, src, count); \
NativeEndian::NAME<T>(aDst, aSrc, aCount); \
}
WRAP_COPYFROM(copyAndSwapFromLittleEndian)
@ -75,9 +83,9 @@ WRAP_COPYFROM(copyAndSwapFromNetworkOrder)
#define WRAP_IN_PLACE(NAME) \
template<typename T> \
void \
NAME(T* p, size_t count) \
NAME(T* aP, size_t aCount) \
{ \
NativeEndian::NAME<T>(p, count); \
NativeEndian::NAME<T>(aP, aCount); \
}
WRAP_IN_PLACE(swapToLittleEndianInPlace)
WRAP_IN_PLACE(swapFromLittleEndianInPlace)
@ -86,17 +94,18 @@ WRAP_IN_PLACE(swapFromBigEndianInPlace)
WRAP_IN_PLACE(swapToNetworkOrderInPlace)
WRAP_IN_PLACE(swapFromNetworkOrderInPlace)
enum SwapExpectation {
enum SwapExpectation
{
Swap,
NoSwap
};
template<typename T, size_t Count>
void
TestBulkSwapToSub(enum SwapExpectation expectSwap,
const T (&values)[Count],
void (*swapperFunc)(void*, const T*, size_t),
T (*readerFunc)(const void*))
TestBulkSwapToSub(enum SwapExpectation aExpectSwap,
const T (&aValues)[Count],
void (*aSwapperFunc)(void*, const T*, size_t),
T (*aReaderFunc)(const void*))
{
const size_t arraySize = 2 * Count;
const size_t bufferSize = arraySize * sizeof(T);
@ -111,20 +120,20 @@ TestBulkSwapToSub(enum SwapExpectation expectSwap,
for (size_t startPosition = 0; startPosition < sizeof(T); ++startPosition) {
for (size_t nValues = 0; nValues < Count; ++nValues) {
memset(buffer, fillValue, bufferSize);
swapperFunc(buffer + startPosition, values, nValues);
aSwapperFunc(buffer + startPosition, aValues, nValues);
MOZ_RELEASE_ASSERT(memcmp(buffer, checkBuffer, startPosition) == 0);
size_t valuesEndPosition = startPosition + sizeof(T) * nValues;
MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
checkBuffer + valuesEndPosition,
bufferSize - valuesEndPosition) == 0);
if (expectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, values,
nValues * sizeof(T)) == 0);
checkBuffer + valuesEndPosition,
bufferSize - valuesEndPosition) == 0);
if (aExpectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
nValues * sizeof(T)) == 0);
}
for (size_t i = 0; i < nValues; ++i) {
MOZ_RELEASE_ASSERT(readerFunc(buffer + startPosition + sizeof(T) * i) ==
values[i]);
MOZ_RELEASE_ASSERT(
aReaderFunc(buffer + startPosition + sizeof(T) * i) == aValues[i]);
}
}
}
@ -132,10 +141,10 @@ TestBulkSwapToSub(enum SwapExpectation expectSwap,
template<typename T, size_t Count>
void
TestBulkSwapFromSub(enum SwapExpectation expectSwap,
const T (&values)[Count],
void (*swapperFunc)(T*, const void*, size_t),
T (*readerFunc)(const void*))
TestBulkSwapFromSub(enum SwapExpectation aExpectSwap,
const T (&aValues)[Count],
void (*aSwapperFunc)(T*, const void*, size_t),
T (*aReaderFunc)(const void*))
{
const size_t arraySize = 2 * Count;
const size_t bufferSize = arraySize * sizeof(T);
@ -148,19 +157,21 @@ TestBulkSwapFromSub(enum SwapExpectation expectSwap,
for (size_t startPosition = 0; startPosition < Count; ++startPosition) {
for (size_t nValues = 0; nValues < (Count - startPosition); ++nValues) {
memset(buffer, fillValue, bufferSize);
swapperFunc(buffer + startPosition, values, nValues);
aSwapperFunc(buffer + startPosition, aValues, nValues);
MOZ_RELEASE_ASSERT(memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
size_t valuesEndPosition = startPosition + nValues;
MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
checkBuffer + valuesEndPosition,
(arraySize - valuesEndPosition) * sizeof(T)) == 0);
if (expectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, values,
if (aExpectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
nValues * sizeof(T)) == 0);
}
for (size_t i = 0; i < nValues; ++i)
MOZ_RELEASE_ASSERT(readerFunc(buffer + startPosition + i) == values[i]);
for (size_t i = 0; i < nValues; ++i) {
MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == aValues[i]);
}
}
}
}
@ -168,10 +179,10 @@ TestBulkSwapFromSub(enum SwapExpectation expectSwap,
template<typename T, size_t Count>
void
TestBulkInPlaceSub(enum SwapExpectation expectSwap,
const T (&values)[Count],
void (*swapperFunc)(T* p, size_t),
T (*readerFunc)(const void*))
TestBulkInPlaceSub(enum SwapExpectation aExpectSwap,
const T (&aValues)[Count],
void (*aSwapperFunc)(T*, size_t),
T (*aReaderFunc)(const void*))
{
const size_t bufferCount = 4 * Count;
const size_t bufferSize = bufferCount * sizeof(T);
@ -186,20 +197,22 @@ TestBulkInPlaceSub(enum SwapExpectation expectSwap,
for (size_t startPosition = 0; startPosition < Count; ++startPosition) {
for (size_t nValues = 0; nValues < Count; ++nValues) {
memset(buffer, fillValue, bufferSize);
memcpy(buffer + startPosition, values, nValues * sizeof(T));
swapperFunc(buffer + startPosition, nValues);
memcpy(buffer + startPosition, aValues, nValues * sizeof(T));
aSwapperFunc(buffer + startPosition, nValues);
MOZ_RELEASE_ASSERT(memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(buffer, checkBuffer, startPosition * sizeof(T)) == 0);
size_t valuesEndPosition = startPosition + nValues;
MOZ_RELEASE_ASSERT(memcmp(buffer + valuesEndPosition,
checkBuffer + valuesEndPosition,
bufferSize - valuesEndPosition * sizeof(T)) == 0);
if (expectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, values,
nValues * sizeof(T)) == 0);
checkBuffer + valuesEndPosition,
bufferSize - valuesEndPosition * sizeof(T)) == 0);
if (aExpectSwap == NoSwap) {
MOZ_RELEASE_ASSERT(memcmp(buffer + startPosition, aValues,
nValues * sizeof(T)) == 0);
}
for (size_t i = 0; i < nValues; ++i) {
MOZ_RELEASE_ASSERT(aReaderFunc(buffer + startPosition + i) == aValues[i]);
}
for (size_t i = 0; i < nValues; ++i)
MOZ_RELEASE_ASSERT(readerFunc(buffer + startPosition + i) == values[i]);
}
}
}
@ -209,12 +222,12 @@ struct Reader
{
};
#define SPECIALIZE_READER(TYPE, READ_FUNC) \
template<> \
struct Reader<TYPE> \
{ \
static TYPE readLE(const void* p) { return LittleEndian::READ_FUNC(p); } \
static TYPE readBE(const void* p) { return BigEndian::READ_FUNC(p); } \
#define SPECIALIZE_READER(TYPE, READ_FUNC) \
template<> \
struct Reader<TYPE> \
{ \
static TYPE readLE(const void* aP) { return LittleEndian::READ_FUNC(aP); }\
static TYPE readBE(const void* aP) { return BigEndian::READ_FUNC(aP); } \
};
SPECIALIZE_READER(uint16_t, readUint16)
@ -226,129 +239,190 @@ SPECIALIZE_READER(int64_t, readInt64)
template<typename T, size_t Count>
void
TestBulkSwap(const T (&bytes)[Count])
TestBulkSwap(const T (&aBytes)[Count])
{
#if MOZ_LITTLE_ENDIAN
TestBulkSwapToSub(Swap, bytes, copyAndSwapToBigEndian<T>, Reader<T>::readBE);
TestBulkSwapFromSub(Swap, bytes, copyAndSwapFromBigEndian<T>, Reader<T>::readBE);
TestBulkSwapToSub(Swap, bytes, copyAndSwapToNetworkOrder<T>, Reader<T>::readBE);
TestBulkSwapFromSub(Swap, bytes, copyAndSwapFromNetworkOrder<T>, Reader<T>::readBE);
TestBulkSwapToSub(Swap, aBytes, copyAndSwapToBigEndian<T>,
Reader<T>::readBE);
TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromBigEndian<T>,
Reader<T>::readBE);
TestBulkSwapToSub(Swap, aBytes, copyAndSwapToNetworkOrder<T>,
Reader<T>::readBE);
TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromNetworkOrder<T>,
Reader<T>::readBE);
#else
TestBulkSwapToSub(Swap, bytes, copyAndSwapToLittleEndian<T>, Reader<T>::readLE);
TestBulkSwapFromSub(Swap, bytes, copyAndSwapFromLittleEndian<T>, Reader<T>::readLE);
TestBulkSwapToSub(Swap, aBytes, copyAndSwapToLittleEndian<T>,
Reader<T>::readLE);
TestBulkSwapFromSub(Swap, aBytes, copyAndSwapFromLittleEndian<T>,
Reader<T>::readLE);
#endif
}
template<typename T, size_t Count>
void
TestBulkNoSwap(const T (&bytes)[Count])
TestBulkNoSwap(const T (&aBytes)[Count])
{
#if MOZ_LITTLE_ENDIAN
TestBulkSwapToSub(NoSwap, bytes, copyAndSwapToLittleEndian<T>, Reader<T>::readLE);
TestBulkSwapFromSub(NoSwap, bytes, copyAndSwapFromLittleEndian<T>, Reader<T>::readLE);
TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToLittleEndian<T>,
Reader<T>::readLE);
TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromLittleEndian<T>,
Reader<T>::readLE);
#else
TestBulkSwapToSub(NoSwap, bytes, copyAndSwapToBigEndian<T>, Reader<T>::readBE);
TestBulkSwapFromSub(NoSwap, bytes, copyAndSwapFromBigEndian<T>, Reader<T>::readBE);
TestBulkSwapToSub(NoSwap, bytes, copyAndSwapToNetworkOrder<T>, Reader<T>::readBE);
TestBulkSwapFromSub(NoSwap, bytes, copyAndSwapFromNetworkOrder<T>, Reader<T>::readBE);
TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToBigEndian<T>,
Reader<T>::readBE);
TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromBigEndian<T>,
Reader<T>::readBE);
TestBulkSwapToSub(NoSwap, aBytes, copyAndSwapToNetworkOrder<T>,
Reader<T>::readBE);
TestBulkSwapFromSub(NoSwap, aBytes, copyAndSwapFromNetworkOrder<T>,
Reader<T>::readBE);
#endif
}
template<typename T, size_t Count>
void
TestBulkInPlaceSwap(const T (&bytes)[Count])
TestBulkInPlaceSwap(const T (&aBytes)[Count])
{
#if MOZ_LITTLE_ENDIAN
TestBulkInPlaceSub(Swap, bytes, swapToBigEndianInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(Swap, bytes, swapFromBigEndianInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(Swap, bytes, swapToNetworkOrderInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(Swap, bytes, swapFromNetworkOrderInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(Swap, aBytes, swapToBigEndianInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(Swap, aBytes, swapFromBigEndianInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(Swap, aBytes, swapToNetworkOrderInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(Swap, aBytes, swapFromNetworkOrderInPlace<T>,
Reader<T>::readBE);
#else
TestBulkInPlaceSub(Swap, bytes, swapToLittleEndianInPlace<T>, Reader<T>::readLE);
TestBulkInPlaceSub(Swap, bytes, swapFromLittleEndianInPlace<T>, Reader<T>::readLE);
TestBulkInPlaceSub(Swap, aBytes, swapToLittleEndianInPlace<T>,
Reader<T>::readLE);
TestBulkInPlaceSub(Swap, aBytes, swapFromLittleEndianInPlace<T>,
Reader<T>::readLE);
#endif
}
template<typename T, size_t Count>
void
TestBulkInPlaceNoSwap(const T (&bytes)[Count])
TestBulkInPlaceNoSwap(const T (&aBytes)[Count])
{
#if MOZ_LITTLE_ENDIAN
TestBulkInPlaceSub(NoSwap, bytes, swapToLittleEndianInPlace<T>, Reader<T>::readLE);
TestBulkInPlaceSub(NoSwap, bytes, swapFromLittleEndianInPlace<T>, Reader<T>::readLE);
TestBulkInPlaceSub(NoSwap, aBytes, swapToLittleEndianInPlace<T>,
Reader<T>::readLE);
TestBulkInPlaceSub(NoSwap, aBytes, swapFromLittleEndianInPlace<T>,
Reader<T>::readLE);
#else
TestBulkInPlaceSub(NoSwap, bytes, swapToBigEndianInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, bytes, swapFromBigEndianInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, bytes, swapToNetworkOrderInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, bytes, swapFromNetworkOrderInPlace<T>, Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, aBytes, swapToBigEndianInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, aBytes, swapFromBigEndianInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, aBytes, swapToNetworkOrderInPlace<T>,
Reader<T>::readBE);
TestBulkInPlaceSub(NoSwap, aBytes, swapFromNetworkOrderInPlace<T>,
Reader<T>::readBE);
#endif
}
int
main()
{
static const uint8_t unsigned_bytes[16] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };
static const int8_t signed_bytes[16] = { -0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08,
-0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08 };
static const uint16_t uint16_values[8] = { 0x102, 0x304, 0x506, 0x708, 0x102, 0x304, 0x506, 0x708 };
static const int16_t int16_values[8] = { int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8),
int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8) };
static const uint32_t uint32_values[4] = { 0x1020304, 0x5060708, 0x1020304, 0x5060708 };
static const int32_t int32_values[4] = { int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8),
int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8) };
static const uint64_t uint64_values[2] = { 0x102030405060708, 0x102030405060708 };
static const int64_t int64_values[2] = { int64_t(0xf1f2f3f4f5f6f7f8),
int64_t(0xf1f2f3f4f5f6f7f8) };
static const uint8_t unsigned_bytes[16] = {
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8
};
static const int8_t signed_bytes[16] = {
-0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08,
-0x0f, -0x0e, -0x0d, -0x0c, -0x0b, -0x0a, -0x09, -0x08
};
static const uint16_t uint16_values[8] = {
0x102, 0x304, 0x506, 0x708, 0x102, 0x304, 0x506, 0x708
};
static const int16_t int16_values[8] = {
int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8),
int16_t(0xf1f2), int16_t(0xf3f4), int16_t(0xf5f6), int16_t(0xf7f8)
};
static const uint32_t uint32_values[4] = {
0x1020304, 0x5060708, 0x1020304, 0x5060708
};
static const int32_t int32_values[4] = {
int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8),
int32_t(0xf1f2f3f4), int32_t(0xf5f6f7f8)
};
static const uint64_t uint64_values[2] = {
0x102030405060708, 0x102030405060708
};
static const int64_t int64_values[2] = {
int64_t(0xf1f2f3f4f5f6f7f8), int64_t(0xf1f2f3f4f5f6f7f8)
};
uint8_t buffer[8];
MOZ_RELEASE_ASSERT(LittleEndian::readUint16(&unsigned_bytes[0]) == 0x201);
MOZ_RELEASE_ASSERT(BigEndian::readUint16(&unsigned_bytes[0]) == 0x102);
MOZ_RELEASE_ASSERT(LittleEndian::readUint32(&unsigned_bytes[0]) == 0x4030201U);
MOZ_RELEASE_ASSERT(BigEndian::readUint32(&unsigned_bytes[0]) == 0x1020304U);
MOZ_RELEASE_ASSERT(
LittleEndian::readUint32(&unsigned_bytes[0]) == 0x4030201U);
MOZ_RELEASE_ASSERT(
BigEndian::readUint32(&unsigned_bytes[0]) == 0x1020304U);
MOZ_RELEASE_ASSERT(LittleEndian::readUint64(&unsigned_bytes[0]) == 0x807060504030201ULL);
MOZ_RELEASE_ASSERT(BigEndian::readUint64(&unsigned_bytes[0]) == 0x102030405060708ULL);
MOZ_RELEASE_ASSERT(
LittleEndian::readUint64(&unsigned_bytes[0]) == 0x807060504030201ULL);
MOZ_RELEASE_ASSERT(
BigEndian::readUint64(&unsigned_bytes[0]) == 0x102030405060708ULL);
LittleEndian::writeUint16(&buffer[0], 0x201);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
BigEndian::writeUint16(&buffer[0], 0x102);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint16_t)) == 0);
LittleEndian::writeUint32(&buffer[0], 0x4030201U);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
BigEndian::writeUint32(&buffer[0], 0x1020304U);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint32_t)) == 0);
LittleEndian::writeUint64(&buffer[0], 0x807060504030201ULL);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
BigEndian::writeUint64(&buffer[0], 0x102030405060708ULL);
MOZ_RELEASE_ASSERT(memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&unsigned_bytes[0], &buffer[0], sizeof(uint64_t)) == 0);
MOZ_RELEASE_ASSERT(LittleEndian::readInt16(&signed_bytes[0]) == int16_t(0xf2f1));
MOZ_RELEASE_ASSERT(BigEndian::readInt16(&signed_bytes[0]) == int16_t(0xf1f2));
MOZ_RELEASE_ASSERT(
LittleEndian::readInt16(&signed_bytes[0]) == int16_t(0xf2f1));
MOZ_RELEASE_ASSERT(
BigEndian::readInt16(&signed_bytes[0]) == int16_t(0xf1f2));
MOZ_RELEASE_ASSERT(LittleEndian::readInt32(&signed_bytes[0]) == int32_t(0xf4f3f2f1));
MOZ_RELEASE_ASSERT(BigEndian::readInt32(&signed_bytes[0]) == int32_t(0xf1f2f3f4));
MOZ_RELEASE_ASSERT(
LittleEndian::readInt32(&signed_bytes[0]) == int32_t(0xf4f3f2f1));
MOZ_RELEASE_ASSERT(
BigEndian::readInt32(&signed_bytes[0]) == int32_t(0xf1f2f3f4));
MOZ_RELEASE_ASSERT(LittleEndian::readInt64(&signed_bytes[0]) == int64_t(0xf8f7f6f5f4f3f2f1LL));
MOZ_RELEASE_ASSERT(BigEndian::readInt64(&signed_bytes[0]) == int64_t(0xf1f2f3f4f5f6f7f8LL));
MOZ_RELEASE_ASSERT(
LittleEndian::readInt64(&signed_bytes[0]) == int64_t(0xf8f7f6f5f4f3f2f1LL));
MOZ_RELEASE_ASSERT(
BigEndian::readInt64(&signed_bytes[0]) == int64_t(0xf1f2f3f4f5f6f7f8LL));
LittleEndian::writeInt16(&buffer[0], int16_t(0xf2f1));
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
BigEndian::writeInt16(&buffer[0], int16_t(0xf1f2));
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int16_t)) == 0);
LittleEndian::writeInt32(&buffer[0], 0xf4f3f2f1);
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
BigEndian::writeInt32(&buffer[0], 0xf1f2f3f4);
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int32_t)) == 0);
LittleEndian::writeInt64(&buffer[0], 0xf8f7f6f5f4f3f2f1LL);
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
BigEndian::writeInt64(&buffer[0], 0xf1f2f3f4f5f6f7f8LL);
MOZ_RELEASE_ASSERT(memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
MOZ_RELEASE_ASSERT(
memcmp(&signed_bytes[0], &buffer[0], sizeof(int64_t)) == 0);
TestSingleSwap(uint16_t(0xf2f1), uint16_t(0xf1f2));
TestSingleSwap(uint32_t(0xf4f3f2f1), uint32_t(0xf1f2f3f4));

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -7,7 +8,8 @@
using namespace mozilla;
enum SeaBird {
enum SeaBird
{
PENGUIN,
ALBATROSS,
FULMAR,
@ -30,201 +32,216 @@ enum SeaBird {
AUK
};
class EnumSetSuite {
public:
EnumSetSuite()
: mAlcidae(),
mDiomedeidae(ALBATROSS),
mPetrelProcellariidae(GADFLY_PETREL, TRUE_PETREL),
mNonPetrelProcellariidae(FULMAR, PRION, SHEARWATER),
mPetrels(GADFLY_PETREL, TRUE_PETREL, DIVING_PETREL, STORM_PETREL)
{ }
class EnumSetSuite
{
public:
EnumSetSuite()
: mAlcidae()
, mDiomedeidae(ALBATROSS)
, mPetrelProcellariidae(GADFLY_PETREL, TRUE_PETREL)
, mNonPetrelProcellariidae(FULMAR, PRION, SHEARWATER)
, mPetrels(GADFLY_PETREL, TRUE_PETREL, DIVING_PETREL, STORM_PETREL)
{ }
void runTests() {
testSize();
testContains();
testAddTo();
testAdd();
testAddAll();
testUnion();
testRemoveFrom();
testRemove();
testRemoveAllFrom();
testRemoveAll();
testIntersect();
testInsersection();
testEquality();
testDuplicates();
}
void runTests()
{
testSize();
testContains();
testAddTo();
testAdd();
testAddAll();
testUnion();
testRemoveFrom();
testRemove();
testRemoveAllFrom();
testRemoveAll();
testIntersect();
testInsersection();
testEquality();
testDuplicates();
}
private:
void testSize() {
MOZ_RELEASE_ASSERT(mAlcidae.size() == 0);
MOZ_RELEASE_ASSERT(mDiomedeidae.size() == 1);
MOZ_RELEASE_ASSERT(mPetrelProcellariidae.size() == 2);
MOZ_RELEASE_ASSERT(mNonPetrelProcellariidae.size() == 3);
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
}
private:
void testSize()
{
MOZ_RELEASE_ASSERT(mAlcidae.size() == 0);
MOZ_RELEASE_ASSERT(mDiomedeidae.size() == 1);
MOZ_RELEASE_ASSERT(mPetrelProcellariidae.size() == 2);
MOZ_RELEASE_ASSERT(mNonPetrelProcellariidae.size() == 3);
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
}
void testContains() {
MOZ_RELEASE_ASSERT(!mPetrels.contains(PENGUIN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(ALBATROSS));
MOZ_RELEASE_ASSERT(!mPetrels.contains(FULMAR));
MOZ_RELEASE_ASSERT(!mPetrels.contains(PRION));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SHEARWATER));
MOZ_RELEASE_ASSERT(mPetrels.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(!mPetrels.contains(PELICAN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(GANNET));
MOZ_RELEASE_ASSERT(!mPetrels.contains(BOOBY));
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(!mPetrels.contains(FRIGATEBIRD));
MOZ_RELEASE_ASSERT(!mPetrels.contains(TROPICBIRD));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SKUA));
MOZ_RELEASE_ASSERT(!mPetrels.contains(GULL));
MOZ_RELEASE_ASSERT(!mPetrels.contains(TERN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SKIMMER));
MOZ_RELEASE_ASSERT(!mPetrels.contains(AUK));
}
void testContains()
{
MOZ_RELEASE_ASSERT(!mPetrels.contains(PENGUIN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(ALBATROSS));
MOZ_RELEASE_ASSERT(!mPetrels.contains(FULMAR));
MOZ_RELEASE_ASSERT(!mPetrels.contains(PRION));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SHEARWATER));
MOZ_RELEASE_ASSERT(mPetrels.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(mPetrels.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(!mPetrels.contains(PELICAN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(GANNET));
MOZ_RELEASE_ASSERT(!mPetrels.contains(BOOBY));
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(!mPetrels.contains(FRIGATEBIRD));
MOZ_RELEASE_ASSERT(!mPetrels.contains(TROPICBIRD));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SKUA));
MOZ_RELEASE_ASSERT(!mPetrels.contains(GULL));
MOZ_RELEASE_ASSERT(!mPetrels.contains(TERN));
MOZ_RELEASE_ASSERT(!mPetrels.contains(SKIMMER));
MOZ_RELEASE_ASSERT(!mPetrels.contains(AUK));
}
void testCopy() {
EnumSet<SeaBird> likes = mPetrels;
likes -= TRUE_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
void testCopy()
{
EnumSet<SeaBird> likes = mPetrels;
likes -= TRUE_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(likes.size() == 3);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
MOZ_RELEASE_ASSERT(likes.size() == 3);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testAddTo() {
EnumSet<SeaBird> seen = mPetrels;
seen += CORMORANT;
seen += TRUE_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(seen.size() == 5);
MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
}
void testAddTo()
{
EnumSet<SeaBird> seen = mPetrels;
seen += CORMORANT;
seen += TRUE_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(seen.size() == 5);
MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
}
void testAdd() {
EnumSet<SeaBird> seen = mPetrels + CORMORANT +
STORM_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(seen.size() == 5);
MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
}
void testAdd()
{
EnumSet<SeaBird> seen = mPetrels + CORMORANT + STORM_PETREL;
MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
MOZ_RELEASE_ASSERT(seen.size() == 5);
MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
}
void testAddAll() {
EnumSet<SeaBird> procellariidae;
procellariidae += mPetrelProcellariidae;
procellariidae += mNonPetrelProcellariidae;
MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
void testAddAll()
{
EnumSet<SeaBird> procellariidae;
procellariidae += mPetrelProcellariidae;
procellariidae += mNonPetrelProcellariidae;
MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
// Both procellariidae and mPetrels include GADFLY_PERTEL and TRUE_PETREL
EnumSet<SeaBird> procellariiformes;
procellariiformes += mDiomedeidae;
procellariiformes += procellariidae;
procellariiformes += mPetrels;
MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
}
// Both procellariidae and mPetrels include GADFLY_PERTEL and TRUE_PETREL
EnumSet<SeaBird> procellariiformes;
procellariiformes += mDiomedeidae;
procellariiformes += procellariidae;
procellariiformes += mPetrels;
MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
}
void testUnion() {
EnumSet<SeaBird> procellariidae = mPetrelProcellariidae +
mNonPetrelProcellariidae;
MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
void testUnion()
{
EnumSet<SeaBird> procellariidae = mPetrelProcellariidae +
mNonPetrelProcellariidae;
MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
// Both procellariidae and mPetrels include GADFLY_PETREL and TRUE_PETREL
EnumSet<SeaBird> procellariiformes = mDiomedeidae + procellariidae +
mPetrels;
MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
}
// Both procellariidae and mPetrels include GADFLY_PETREL and TRUE_PETREL
EnumSet<SeaBird> procellariiformes = mDiomedeidae + procellariidae +
mPetrels;
MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
}
void testRemoveFrom() {
EnumSet<SeaBird> likes = mPetrels;
likes -= TRUE_PETREL;
likes -= DIVING_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemoveFrom()
{
EnumSet<SeaBird> likes = mPetrels;
likes -= TRUE_PETREL;
likes -= DIVING_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemove() {
EnumSet<SeaBird> likes = mPetrels - TRUE_PETREL -
DIVING_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemove()
{
EnumSet<SeaBird> likes = mPetrels - TRUE_PETREL - DIVING_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemoveAllFrom() {
EnumSet<SeaBird> likes = mPetrels;
likes -= mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemoveAllFrom()
{
EnumSet<SeaBird> likes = mPetrels;
likes -= mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemoveAll() {
EnumSet<SeaBird> likes = mPetrels - mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testRemoveAll()
{
EnumSet<SeaBird> likes = mPetrels - mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
}
void testIntersect() {
EnumSet<SeaBird> likes = mPetrels;
likes &= mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
}
void testIntersect()
{
EnumSet<SeaBird> likes = mPetrels;
likes &= mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
}
void testInsersection() {
EnumSet<SeaBird> likes = mPetrels & mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
}
void testInsersection()
{
EnumSet<SeaBird> likes = mPetrels & mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes.size() == 2);
MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
}
void testEquality() {
EnumSet<SeaBird> likes = mPetrels & mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes == EnumSet<SeaBird>(GADFLY_PETREL,
TRUE_PETREL));
}
void testEquality()
{
EnumSet<SeaBird> likes = mPetrels & mPetrelProcellariidae;
MOZ_RELEASE_ASSERT(likes == EnumSet<SeaBird>(GADFLY_PETREL,
TRUE_PETREL));
}
void testDuplicates() {
EnumSet<SeaBird> likes = mPetrels;
likes += GADFLY_PETREL;
likes += TRUE_PETREL;
likes += DIVING_PETREL;
likes += STORM_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 4);
MOZ_RELEASE_ASSERT(likes == mPetrels);
}
void testDuplicates()
{
EnumSet<SeaBird> likes = mPetrels;
likes += GADFLY_PETREL;
likes += TRUE_PETREL;
likes += DIVING_PETREL;
likes += STORM_PETREL;
MOZ_RELEASE_ASSERT(likes.size() == 4);
MOZ_RELEASE_ASSERT(likes == mPetrels);
}
EnumSet<SeaBird> mAlcidae;
EnumSet<SeaBird> mDiomedeidae;
EnumSet<SeaBird> mPetrelProcellariidae;
EnumSet<SeaBird> mNonPetrelProcellariidae;
EnumSet<SeaBird> mPetrels;
EnumSet<SeaBird> mAlcidae;
EnumSet<SeaBird> mDiomedeidae;
EnumSet<SeaBird> mPetrelProcellariidae;
EnumSet<SeaBird> mNonPetrelProcellariidae;
EnumSet<SeaBird> mPetrels;
};
int main()
int
main()
{
EnumSetSuite suite;
suite.runTests();

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -24,20 +25,22 @@ using mozilla::PositiveInfinity;
using mozilla::SpecificNaN;
using mozilla::UnspecifiedNaN;
#define A(a) MOZ_RELEASE_ASSERT(a)
template<typename T>
static void
ShouldBeIdentical(T d1, T d2)
ShouldBeIdentical(T aD1, T aD2)
{
MOZ_RELEASE_ASSERT(NumbersAreIdentical(d1, d2));
MOZ_RELEASE_ASSERT(NumbersAreIdentical(d2, d1));
A(NumbersAreIdentical(aD1, aD2));
A(NumbersAreIdentical(aD2, aD1));
}
template<typename T>
static void
ShouldNotBeIdentical(T d1, T d2)
ShouldNotBeIdentical(T aD1, T aD2)
{
MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d1, d2));
MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d2, d1));
A(!NumbersAreIdentical(aD1, aD2));
A(!NumbersAreIdentical(aD2, aD1));
}
static void
@ -77,8 +80,10 @@ TestDoublesAreIdentical()
for (unsigned i = 0; i < 52; i++) {
for (unsigned j = 0; j < 52; j++) {
for (unsigned sign = 0; i < 2; i++) {
ShouldBeIdentical(SpecificNaN<double>(0, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j));
ShouldBeIdentical(SpecificNaN<double>(1, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j));
ShouldBeIdentical(SpecificNaN<double>(0, 1ULL << i),
SpecificNaN<double>(sign, 1ULL << j));
ShouldBeIdentical(SpecificNaN<double>(1, 1ULL << i),
SpecificNaN<double>(sign, 1ULL << j));
ShouldBeIdentical(SpecificNaN<double>(0, Mask & ~(1ULL << i)),
SpecificNaN<double>(sign, Mask & ~(1ULL << j)));
@ -87,20 +92,34 @@ TestDoublesAreIdentical()
}
}
}
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x8000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x4000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x2000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x1000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0800000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0400000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0200000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0100000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0080000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0040000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0020000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0010000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xff0ffffffffffULL));
ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xfffffffffff0fULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x8000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x4000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x2000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x1000000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0800000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0400000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0200000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0100000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0080000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0040000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0020000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(0, 17),
SpecificNaN<double>(0, 0x0010000000000ULL));
ShouldBeIdentical(SpecificNaN<double>(1, 17),
SpecificNaN<double>(0, 0xff0ffffffffffULL));
ShouldBeIdentical(SpecificNaN<double>(1, 17),
SpecificNaN<double>(0, 0xfffffffffff0fULL));
ShouldNotBeIdentical(UnspecifiedNaN<double>(), +0.0);
ShouldNotBeIdentical(UnspecifiedNaN<double>(), -0.0);
@ -147,8 +166,10 @@ TestFloatsAreIdentical()
for (unsigned i = 0; i < 23; i++) {
for (unsigned j = 0; j < 23; j++) {
for (unsigned sign = 0; i < 2; i++) {
ShouldBeIdentical(SpecificNaN<float>(0, 1UL << i), SpecificNaN<float>(sign, 1UL << j));
ShouldBeIdentical(SpecificNaN<float>(1, 1UL << i), SpecificNaN<float>(sign, 1UL << j));
ShouldBeIdentical(SpecificNaN<float>(0, 1UL << i),
SpecificNaN<float>(sign, 1UL << j));
ShouldBeIdentical(SpecificNaN<float>(1, 1UL << i),
SpecificNaN<float>(sign, 1UL << j));
ShouldBeIdentical(SpecificNaN<float>(0, Mask & ~(1UL << i)),
SpecificNaN<float>(sign, Mask & ~(1UL << j)));
@ -190,33 +211,43 @@ TestAreIdentical()
static void
TestDoubleExponentComponent()
{
MOZ_RELEASE_ASSERT(ExponentComponent(0.0) == -int_fast16_t(FloatingPoint<double>::kExponentBias));
MOZ_RELEASE_ASSERT(ExponentComponent(-0.0) == -int_fast16_t(FloatingPoint<double>::kExponentBias));
MOZ_RELEASE_ASSERT(ExponentComponent(0.125) == -3);
MOZ_RELEASE_ASSERT(ExponentComponent(0.5) == -1);
MOZ_RELEASE_ASSERT(ExponentComponent(1.0) == 0);
MOZ_RELEASE_ASSERT(ExponentComponent(1.5) == 0);
MOZ_RELEASE_ASSERT(ExponentComponent(2.0) == 1);
MOZ_RELEASE_ASSERT(ExponentComponent(7.0) == 2);
MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<double>()) == FloatingPoint<double>::kExponentBias + 1);
MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<double>()) == FloatingPoint<double>::kExponentBias + 1);
MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<double>()) == FloatingPoint<double>::kExponentBias + 1);
A(ExponentComponent(0.0) ==
-int_fast16_t(FloatingPoint<double>::kExponentBias));
A(ExponentComponent(-0.0) ==
-int_fast16_t(FloatingPoint<double>::kExponentBias));
A(ExponentComponent(0.125) == -3);
A(ExponentComponent(0.5) == -1);
A(ExponentComponent(1.0) == 0);
A(ExponentComponent(1.5) == 0);
A(ExponentComponent(2.0) == 1);
A(ExponentComponent(7.0) == 2);
A(ExponentComponent(PositiveInfinity<double>()) ==
FloatingPoint<double>::kExponentBias + 1);
A(ExponentComponent(NegativeInfinity<double>()) ==
FloatingPoint<double>::kExponentBias + 1);
A(ExponentComponent(UnspecifiedNaN<double>()) ==
FloatingPoint<double>::kExponentBias + 1);
}
static void
TestFloatExponentComponent()
{
MOZ_RELEASE_ASSERT(ExponentComponent(0.0f) == -int_fast16_t(FloatingPoint<float>::kExponentBias));
MOZ_RELEASE_ASSERT(ExponentComponent(-0.0f) == -int_fast16_t(FloatingPoint<float>::kExponentBias));
MOZ_RELEASE_ASSERT(ExponentComponent(0.125f) == -3);
MOZ_RELEASE_ASSERT(ExponentComponent(0.5f) == -1);
MOZ_RELEASE_ASSERT(ExponentComponent(1.0f) == 0);
MOZ_RELEASE_ASSERT(ExponentComponent(1.5f) == 0);
MOZ_RELEASE_ASSERT(ExponentComponent(2.0f) == 1);
MOZ_RELEASE_ASSERT(ExponentComponent(7.0f) == 2);
MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<float>()) == FloatingPoint<float>::kExponentBias + 1);
MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<float>()) == FloatingPoint<float>::kExponentBias + 1);
MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<float>()) == FloatingPoint<float>::kExponentBias + 1);
A(ExponentComponent(0.0f) ==
-int_fast16_t(FloatingPoint<float>::kExponentBias));
A(ExponentComponent(-0.0f) ==
-int_fast16_t(FloatingPoint<float>::kExponentBias));
A(ExponentComponent(0.125f) == -3);
A(ExponentComponent(0.5f) == -1);
A(ExponentComponent(1.0f) == 0);
A(ExponentComponent(1.5f) == 0);
A(ExponentComponent(2.0f) == 1);
A(ExponentComponent(7.0f) == 2);
A(ExponentComponent(PositiveInfinity<float>()) ==
FloatingPoint<float>::kExponentBias + 1);
A(ExponentComponent(NegativeInfinity<float>()) ==
FloatingPoint<float>::kExponentBias + 1);
A(ExponentComponent(UnspecifiedNaN<float>()) ==
FloatingPoint<float>::kExponentBias + 1);
}
static void
@ -229,136 +260,150 @@ TestExponentComponent()
static void
TestDoublesPredicates()
{
MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<double>()));
MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(1, 17)));;
MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(0, 0xfffffffffff0fULL)));
MOZ_RELEASE_ASSERT(!IsNaN(0.0));
MOZ_RELEASE_ASSERT(!IsNaN(-0.0));
MOZ_RELEASE_ASSERT(!IsNaN(1.0));
MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<double>()));
A(IsNaN(UnspecifiedNaN<double>()));
A(IsNaN(SpecificNaN<double>(1, 17)));;
A(IsNaN(SpecificNaN<double>(0, 0xfffffffffff0fULL)));
A(!IsNaN(0.0));
A(!IsNaN(-0.0));
A(!IsNaN(1.0));
A(!IsNaN(PositiveInfinity<double>()));
A(!IsNaN(NegativeInfinity<double>()));
MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<double>()));
MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<double>()));
MOZ_RELEASE_ASSERT(!IsInfinite(0.0));
MOZ_RELEASE_ASSERT(!IsInfinite(-0.0));
MOZ_RELEASE_ASSERT(!IsInfinite(1.0));
A(IsInfinite(PositiveInfinity<double>()));
A(IsInfinite(NegativeInfinity<double>()));
A(!IsInfinite(UnspecifiedNaN<double>()));
A(!IsInfinite(0.0));
A(!IsInfinite(-0.0));
A(!IsInfinite(1.0));
MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<double>()));
MOZ_RELEASE_ASSERT(IsFinite(0.0));
MOZ_RELEASE_ASSERT(IsFinite(-0.0));
MOZ_RELEASE_ASSERT(IsFinite(1.0));
A(!IsFinite(PositiveInfinity<double>()));
A(!IsFinite(NegativeInfinity<double>()));
A(!IsFinite(UnspecifiedNaN<double>()));
A(IsFinite(0.0));
A(IsFinite(-0.0));
A(IsFinite(1.0));
MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<double>()));
MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<double>()));
MOZ_RELEASE_ASSERT(IsNegative(-0.0));
MOZ_RELEASE_ASSERT(!IsNegative(0.0));
MOZ_RELEASE_ASSERT(IsNegative(-1.0));
MOZ_RELEASE_ASSERT(!IsNegative(1.0));
A(!IsNegative(PositiveInfinity<double>()));
A(IsNegative(NegativeInfinity<double>()));
A(IsNegative(-0.0));
A(!IsNegative(0.0));
A(IsNegative(-1.0));
A(!IsNegative(1.0));
MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<double>()));
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 17)));;
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 0xfffffffffff0fULL)));
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 17)));;
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 0xfffffffffff0fULL)));
MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<double>()));
MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0));
MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0));
MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0));
MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0));
A(!IsNegativeZero(PositiveInfinity<double>()));
A(!IsNegativeZero(NegativeInfinity<double>()));
A(!IsNegativeZero(SpecificNaN<double>(1, 17)));;
A(!IsNegativeZero(SpecificNaN<double>(1, 0xfffffffffff0fULL)));
A(!IsNegativeZero(SpecificNaN<double>(0, 17)));;
A(!IsNegativeZero(SpecificNaN<double>(0, 0xfffffffffff0fULL)));
A(!IsNegativeZero(UnspecifiedNaN<double>()));
A(IsNegativeZero(-0.0));
A(!IsNegativeZero(0.0));
A(!IsNegativeZero(-1.0));
A(!IsNegativeZero(1.0));
int32_t i;
MOZ_RELEASE_ASSERT(NumberIsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0, &i));
MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN);
MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX);
MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5, &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MAX) + 0.1, &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MIN) - 0.1, &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<double>(), &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<double>(), &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<double>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5, &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MAX) + 0.1, &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MIN) - 0.1, &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<double>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<double>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<double>(), &i));
A(NumberIsInt32(0.0, &i));
A(i == 0);
A(!NumberIsInt32(-0.0, &i));
A(NumberEqualsInt32(0.0, &i));
A(i == 0);
A(NumberEqualsInt32(-0.0, &i));
A(i == 0);
A(NumberIsInt32(double(INT32_MIN), &i));
A(i == INT32_MIN);
A(NumberIsInt32(double(INT32_MAX), &i));
A(i == INT32_MAX);
A(NumberEqualsInt32(double(INT32_MIN), &i));
A(i == INT32_MIN);
A(NumberEqualsInt32(double(INT32_MAX), &i));
A(i == INT32_MAX);
A(!NumberIsInt32(0.5, &i));
A(!NumberIsInt32(double(INT32_MAX) + 0.1, &i));
A(!NumberIsInt32(double(INT32_MIN) - 0.1, &i));
A(!NumberIsInt32(NegativeInfinity<double>(), &i));
A(!NumberIsInt32(PositiveInfinity<double>(), &i));
A(!NumberIsInt32(UnspecifiedNaN<double>(), &i));
A(!NumberEqualsInt32(0.5, &i));
A(!NumberEqualsInt32(double(INT32_MAX) + 0.1, &i));
A(!NumberEqualsInt32(double(INT32_MIN) - 0.1, &i));
A(!NumberEqualsInt32(NegativeInfinity<double>(), &i));
A(!NumberEqualsInt32(PositiveInfinity<double>(), &i));
A(!NumberEqualsInt32(UnspecifiedNaN<double>(), &i));
}
static void
TestFloatsPredicates()
{
MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<float>()));
MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(1, 17)));;
MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(0, 0x7fff0fUL)));
MOZ_RELEASE_ASSERT(!IsNaN(0.0f));
MOZ_RELEASE_ASSERT(!IsNaN(-0.0f));
MOZ_RELEASE_ASSERT(!IsNaN(1.0f));
MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<float>()));
A(IsNaN(UnspecifiedNaN<float>()));
A(IsNaN(SpecificNaN<float>(1, 17)));;
A(IsNaN(SpecificNaN<float>(0, 0x7fff0fUL)));
A(!IsNaN(0.0f));
A(!IsNaN(-0.0f));
A(!IsNaN(1.0f));
A(!IsNaN(PositiveInfinity<float>()));
A(!IsNaN(NegativeInfinity<float>()));
MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<float>()));
MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<float>()));
MOZ_RELEASE_ASSERT(!IsInfinite(0.0f));
MOZ_RELEASE_ASSERT(!IsInfinite(-0.0f));
MOZ_RELEASE_ASSERT(!IsInfinite(1.0f));
A(IsInfinite(PositiveInfinity<float>()));
A(IsInfinite(NegativeInfinity<float>()));
A(!IsInfinite(UnspecifiedNaN<float>()));
A(!IsInfinite(0.0f));
A(!IsInfinite(-0.0f));
A(!IsInfinite(1.0f));
MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<float>()));
MOZ_RELEASE_ASSERT(IsFinite(0.0f));
MOZ_RELEASE_ASSERT(IsFinite(-0.0f));
MOZ_RELEASE_ASSERT(IsFinite(1.0f));
A(!IsFinite(PositiveInfinity<float>()));
A(!IsFinite(NegativeInfinity<float>()));
A(!IsFinite(UnspecifiedNaN<float>()));
A(IsFinite(0.0f));
A(IsFinite(-0.0f));
A(IsFinite(1.0f));
MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<float>()));
MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<float>()));
MOZ_RELEASE_ASSERT(IsNegative(-0.0f));
MOZ_RELEASE_ASSERT(!IsNegative(0.0f));
MOZ_RELEASE_ASSERT(IsNegative(-1.0f));
MOZ_RELEASE_ASSERT(!IsNegative(1.0f));
A(!IsNegative(PositiveInfinity<float>()));
A(IsNegative(NegativeInfinity<float>()));
A(IsNegative(-0.0f));
A(!IsNegative(0.0f));
A(IsNegative(-1.0f));
A(!IsNegative(1.0f));
MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<float>()));
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 17)));;
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 0x7fff0fUL)));
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 17)));;
MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 0x7fff0fUL)));
MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<float>()));
MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0f));
MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0f));
MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0f));
MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0f));
A(!IsNegativeZero(PositiveInfinity<float>()));
A(!IsNegativeZero(NegativeInfinity<float>()));
A(!IsNegativeZero(SpecificNaN<float>(1, 17)));;
A(!IsNegativeZero(SpecificNaN<float>(1, 0x7fff0fUL)));
A(!IsNegativeZero(SpecificNaN<float>(0, 17)));;
A(!IsNegativeZero(SpecificNaN<float>(0, 0x7fff0fUL)));
A(!IsNegativeZero(UnspecifiedNaN<float>()));
A(IsNegativeZero(-0.0f));
A(!IsNegativeZero(0.0f));
A(!IsNegativeZero(-1.0f));
A(!IsNegativeZero(1.0f));
int32_t i;
const int32_t BIG = 2097151;
MOZ_RELEASE_ASSERT(NumberIsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0f, &i));
MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0);
MOZ_RELEASE_ASSERT(NumberIsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN);
MOZ_RELEASE_ASSERT(NumberIsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN);
MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG);
MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5f, &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(float(BIG) + 0.1f, &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<float>(), &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<float>(), &i));
MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<float>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5f, &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(float(BIG) + 0.1f, &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<float>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<float>(), &i));
MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<float>(), &i));
A(NumberIsInt32(0.0f, &i));
A(i == 0);
A(!NumberIsInt32(-0.0f, &i));
A(NumberEqualsInt32(0.0f, &i));
A(i == 0);
A(NumberEqualsInt32(-0.0f, &i));
A(i == 0);
A(NumberIsInt32(float(INT32_MIN), &i));
A(i == INT32_MIN);
A(NumberIsInt32(float(BIG), &i));
A(i == BIG);
A(NumberEqualsInt32(float(INT32_MIN), &i));
A(i == INT32_MIN);
A(NumberEqualsInt32(float(BIG), &i));
A(i == BIG);
A(!NumberIsInt32(0.5f, &i));
A(!NumberIsInt32(float(BIG) + 0.1f, &i));
A(!NumberIsInt32(NegativeInfinity<float>(), &i));
A(!NumberIsInt32(PositiveInfinity<float>(), &i));
A(!NumberIsInt32(UnspecifiedNaN<float>(), &i));
A(!NumberEqualsInt32(0.5f, &i));
A(!NumberEqualsInt32(float(BIG) + 0.1f, &i));
A(!NumberEqualsInt32(NegativeInfinity<float>(), &i));
A(!NumberEqualsInt32(PositiveInfinity<float>(), &i));
A(!NumberEqualsInt32(UnspecifiedNaN<float>(), &i));
}
static void
@ -377,64 +422,68 @@ TestFloatsAreApproximatelyEqual()
// Additive tests using the default epsilon
// ... around 1.0
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + epsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f + moreThanEpsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f - moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0f, 1.0f + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0f, 1.0f - lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0f, 1.0f + epsilon));
A(FuzzyEqualsAdditive(1.0f, 1.0f - epsilon));
A(!FuzzyEqualsAdditive(1.0f, 1.0f + moreThanEpsilon));
A(!FuzzyEqualsAdditive(1.0f, 1.0f - moreThanEpsilon));
// ... around 1.0e2 (this is near the upper bound of the range where
// adding moreThanEpsilon will still be representable and return false)
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e2f, 1.0e2f + moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + epsilon));
A(!FuzzyEqualsAdditive(1.0e2f, 1.0e2f + moreThanEpsilon));
// ... around 1.0e-10
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + epsilon));
A(!FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + moreThanEpsilon));
// ... straddling 0
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-6f, -1.0e-6f));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, -1.0e-5f));
A(FuzzyEqualsAdditive(1.0e-6f, -1.0e-6f));
A(!FuzzyEqualsAdditive(1.0e-5f, -1.0e-5f));
// Using a small epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-9f));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-11f));
A(FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-9f));
A(!FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-11f));
// Using a big epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e16f));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e14f));
A(FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e16f));
A(!FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e14f));
// Multiplicative tests using the default epsilon
// ... around 1.0
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f - lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f + moreThanEpsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - moreThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0f, 1.0f + lessThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0f, 1.0f - lessThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0f, 1.0f + epsilon));
A(!FuzzyEqualsMultiplicative(1.0f, 1.0f - epsilon));
A(!FuzzyEqualsMultiplicative(1.0f, 1.0f + moreThanEpsilon));
A(!FuzzyEqualsMultiplicative(1.0f, 1.0f - moreThanEpsilon));
// ... around 1.0e10
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (lessThanEpsilon * 1.0e10f)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (moreThanEpsilon * 1.0e10f)));
A(FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (lessThanEpsilon * 1.0e10f)));
A(!FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (moreThanEpsilon * 1.0e10f)));
// ... around 1.0e-10
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (lessThanEpsilon * 1.0e-10f)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (moreThanEpsilon * 1.0e-10f)));
A(FuzzyEqualsMultiplicative(1.0e-10f,
1.0e-10f + (lessThanEpsilon * 1.0e-10f)));
A(!FuzzyEqualsMultiplicative(1.0e-10f,
1.0e-10f + (moreThanEpsilon * 1.0e-10f)));
// ... straddling 0
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f, 1.0e2f));
A(!FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f));
A(FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f, 1.0e2f));
// Using a small epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-4f));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-5f));
A(FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-4f));
A(!FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-5f));
// Using a big epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 2.0f, 1.0f));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 2.0f, 0.1f));
A(FuzzyEqualsMultiplicative(1.0f, 2.0f, 1.0f));
A(!FuzzyEqualsMultiplicative(1.0f, 2.0f, 0.1f));
// "real world case"
float oneThird = 10.0f / 3.0f;
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0f, 3.0f * oneThird));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0f, 3.0f * oneThird));
A(FuzzyEqualsAdditive(10.0f, 3.0f * oneThird));
A(FuzzyEqualsMultiplicative(10.0f, 3.0f * oneThird));
// NaN check
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 8)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 200)));
A(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1)));
A(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 8)));
A(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 1),
SpecificNaN<float>(1, 1)));
A(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 2),
SpecificNaN<float>(0, 200)));
}
static void
@ -446,64 +495,68 @@ TestDoublesAreApproximatelyEqual()
// Additive tests using the default epsilon
// ... around 1.0
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + epsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 + moreThanEpsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 - moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0, 1.0 + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0, 1.0 - lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0, 1.0 + epsilon));
A(FuzzyEqualsAdditive(1.0, 1.0 - epsilon));
A(!FuzzyEqualsAdditive(1.0, 1.0 + moreThanEpsilon));
A(!FuzzyEqualsAdditive(1.0, 1.0 - moreThanEpsilon));
// ... around 1.0e4 (this is near the upper bound of the range where
// adding moreThanEpsilon will still be representable and return false)
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e4, 1.0e4 + moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0e4, 1.0e4 + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0e4, 1.0e4 + epsilon));
A(!FuzzyEqualsAdditive(1.0e4, 1.0e4 + moreThanEpsilon));
// ... around 1.0e-25
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + moreThanEpsilon));
A(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + lessThanEpsilon));
A(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + epsilon));
A(!FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + moreThanEpsilon));
// ... straddling 0
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-13, -1.0e-13));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-12, -1.0e-12));
A(FuzzyEqualsAdditive(1.0e-13, -1.0e-13));
A(!FuzzyEqualsAdditive(1.0e-12, -1.0e-12));
// Using a small epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-29));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-31));
A(FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-29));
A(!FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-31));
// Using a big epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e26));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e24));
A(FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e26));
A(!FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e24));
// Multiplicative tests using the default epsilon
// ... around 1.0
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 - lessThanEpsilon));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - epsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 + moreThanEpsilon));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - moreThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0, 1.0 + lessThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0, 1.0 - lessThanEpsilon));
A(FuzzyEqualsMultiplicative(1.0, 1.0 + epsilon));
A(!FuzzyEqualsMultiplicative(1.0, 1.0 - epsilon));
A(!FuzzyEqualsMultiplicative(1.0, 1.0 + moreThanEpsilon));
A(!FuzzyEqualsMultiplicative(1.0, 1.0 - moreThanEpsilon));
// ... around 1.0e30
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (lessThanEpsilon * 1.0e30)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (moreThanEpsilon * 1.0e30)));
A(FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (lessThanEpsilon * 1.0e30)));
A(!FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (moreThanEpsilon * 1.0e30)));
// ... around 1.0e-30
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (lessThanEpsilon * 1.0e-30)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (moreThanEpsilon * 1.0e-30)));
A(FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (lessThanEpsilon * 1.0e-30)));
A(!FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (moreThanEpsilon * 1.0e-30)));
// ... straddling 0
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6, 1.0e2));
A(!FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6));
A(FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6, 1.0e2));
// Using a small epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-15));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-16));
A(FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-15));
A(!FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-16));
// Using a big epsilon
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 1.0));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 0.1));
A(FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 1.0));
A(!FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 0.1));
// "real world case"
double oneThird = 10.0 / 3.0;
MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0, 3.0 * oneThird));
MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0, 3.0 * oneThird));
A(FuzzyEqualsAdditive(10.0, 3.0 * oneThird));
A(FuzzyEqualsMultiplicative(10.0, 3.0 * oneThird));
// NaN check
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 8)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1)));
MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 200)));
A(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 1),
SpecificNaN<double>(1, 1)));
A(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 2),
SpecificNaN<double>(0, 8)));
A(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 1),
SpecificNaN<double>(1, 1)));
A(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 2),
SpecificNaN<double>(0, 200)));
}
static void
@ -513,6 +566,8 @@ TestAreApproximatelyEqual()
TestDoublesAreApproximatelyEqual();
}
#undef A
int
main()
{
@ -520,4 +575,5 @@ main()
TestExponentComponent();
TestPredicates();
TestAreApproximatelyEqual();
return 0;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -11,12 +12,12 @@
#include <string.h>
/* Output array and poisoning method shared by all tests. */
static char output[32];
static char gOutput[32];
static void
PoisonOutput()
{
memset(output, 0xDA, sizeof(output));
memset(gOutput, 0xDA, sizeof(gOutput));
}
/*
@ -32,48 +33,48 @@ static void
TestPrintSigned8()
{
PoisonOutput();
sprintf(output, "%" PRId8, int8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(output, "-17"));
sprintf(gOutput, "%" PRId8, int8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
PoisonOutput();
sprintf(output, "%" PRIi8, int8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIi8, int8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
}
static void
TestPrintSigned16()
{
PoisonOutput();
sprintf(output, "%" PRId16, int16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(output, "-289"));
sprintf(gOutput, "%" PRId16, int16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
PoisonOutput();
sprintf(output, "%" PRIi16, int16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(output, "728"));
sprintf(gOutput, "%" PRIi16, int16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
}
static void
TestPrintSigned32()
{
PoisonOutput();
sprintf(output, "%" PRId32, int32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(output, "-342178"));
sprintf(gOutput, "%" PRId32, int32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
PoisonOutput();
sprintf(output, "%" PRIi32, int32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(output, "5719283"));
sprintf(gOutput, "%" PRIi32, int32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
}
static void
TestPrintSigned64()
{
PoisonOutput();
sprintf(output, "%" PRId64, int64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(output, "-432157943248732"));
sprintf(gOutput, "%" PRId64, int64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
PoisonOutput();
sprintf(output, "%" PRIi64, int64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(output, "325719232983"));
sprintf(gOutput, "%" PRIi64, int64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
}
static void
@ -89,48 +90,48 @@ static void
TestPrintSignedLeast8()
{
PoisonOutput();
sprintf(output, "%" PRIdLEAST8, int_least8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(output, "-17"));
sprintf(gOutput, "%" PRIdLEAST8, int_least8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
PoisonOutput();
sprintf(output, "%" PRIiLEAST8, int_least8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIiLEAST8, int_least8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
}
static void
TestPrintSignedLeast16()
{
PoisonOutput();
sprintf(output, "%" PRIdLEAST16, int_least16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(output, "-289"));
sprintf(gOutput, "%" PRIdLEAST16, int_least16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
PoisonOutput();
sprintf(output, "%" PRIiLEAST16, int_least16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(output, "728"));
sprintf(gOutput, "%" PRIiLEAST16, int_least16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
}
static void
TestPrintSignedLeast32()
{
PoisonOutput();
sprintf(output, "%" PRIdLEAST32, int_least32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(output, "-342178"));
sprintf(gOutput, "%" PRIdLEAST32, int_least32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
PoisonOutput();
sprintf(output, "%" PRIiLEAST32, int_least32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(output, "5719283"));
sprintf(gOutput, "%" PRIiLEAST32, int_least32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
}
static void
TestPrintSignedLeast64()
{
PoisonOutput();
sprintf(output, "%" PRIdLEAST64, int_least64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(output, "-432157943248732"));
sprintf(gOutput, "%" PRIdLEAST64, int_least64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
PoisonOutput();
sprintf(output, "%" PRIiLEAST64, int_least64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(output, "325719232983"));
sprintf(gOutput, "%" PRIiLEAST64, int_least64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
}
static void
@ -146,48 +147,48 @@ static void
TestPrintSignedFast8()
{
PoisonOutput();
sprintf(output, "%" PRIdFAST8, int_fast8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(output, "-17"));
sprintf(gOutput, "%" PRIdFAST8, int_fast8_t(-17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
PoisonOutput();
sprintf(output, "%" PRIiFAST8, int_fast8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIiFAST8, int_fast8_t(42));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
}
static void
TestPrintSignedFast16()
{
PoisonOutput();
sprintf(output, "%" PRIdFAST16, int_fast16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(output, "-289"));
sprintf(gOutput, "%" PRIdFAST16, int_fast16_t(-289));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
PoisonOutput();
sprintf(output, "%" PRIiFAST16, int_fast16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(output, "728"));
sprintf(gOutput, "%" PRIiFAST16, int_fast16_t(728));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
}
static void
TestPrintSignedFast32()
{
PoisonOutput();
sprintf(output, "%" PRIdFAST32, int_fast32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(output, "-342178"));
sprintf(gOutput, "%" PRIdFAST32, int_fast32_t(-342178));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
PoisonOutput();
sprintf(output, "%" PRIiFAST32, int_fast32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(output, "5719283"));
sprintf(gOutput, "%" PRIiFAST32, int_fast32_t(5719283));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
}
static void
TestPrintSignedFast64()
{
PoisonOutput();
sprintf(output, "%" PRIdFAST64, int_fast64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(output, "-432157943248732"));
sprintf(gOutput, "%" PRIdFAST64, int_fast64_t(-INT64_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
PoisonOutput();
sprintf(output, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(output, "325719232983"));
sprintf(gOutput, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
}
static void
@ -203,24 +204,24 @@ static void
TestPrintSignedMax()
{
PoisonOutput();
sprintf(output, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(output, "-432157943248732"));
sprintf(gOutput, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
PoisonOutput();
sprintf(output, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(output, "325719232983"));
sprintf(gOutput, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
}
static void
TestPrintSignedPtr()
{
PoisonOutput();
sprintf(output, "%" PRIdPTR, intptr_t(reinterpret_cast<void*>(12345678)));
MOZ_RELEASE_ASSERT(!strcmp(output, "12345678"));
sprintf(gOutput, "%" PRIdPTR, intptr_t(reinterpret_cast<void*>(12345678)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "12345678"));
PoisonOutput();
sprintf(output, "%" PRIiPTR, intptr_t(reinterpret_cast<void*>(87654321)));
MOZ_RELEASE_ASSERT(!strcmp(output, "87654321"));
sprintf(gOutput, "%" PRIiPTR, intptr_t(reinterpret_cast<void*>(87654321)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
}
static void
@ -248,80 +249,80 @@ static void
TestPrintUnsigned8()
{
PoisonOutput();
sprintf(output, "%" PRIo8, uint8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIo8, uint8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
PoisonOutput();
sprintf(output, "%" PRIu8, uint8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(output, "17"));
sprintf(gOutput, "%" PRIu8, uint8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
PoisonOutput();
sprintf(output, "%" PRIx8, uint8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a"));
sprintf(gOutput, "%" PRIx8, uint8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
PoisonOutput();
sprintf(output, "%" PRIX8, uint8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CD"));
sprintf(gOutput, "%" PRIX8, uint8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
}
static void
TestPrintUnsigned16()
{
PoisonOutput();
sprintf(output, "%" PRIo16, uint16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(output, "4242"));
sprintf(gOutput, "%" PRIo16, uint16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
PoisonOutput();
sprintf(output, "%" PRIu16, uint16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(output, "1717"));
sprintf(gOutput, "%" PRIu16, uint16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
PoisonOutput();
sprintf(output, "%" PRIx16, uint16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a"));
sprintf(gOutput, "%" PRIx16, uint16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
PoisonOutput();
sprintf(output, "%" PRIX16, uint16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCD"));
sprintf(gOutput, "%" PRIX16, uint16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
}
static void
TestPrintUnsigned32()
{
PoisonOutput();
sprintf(output, "%" PRIo32, uint32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242"));
sprintf(gOutput, "%" PRIo32, uint32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
PoisonOutput();
sprintf(output, "%" PRIu32, uint32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(output, "171717"));
sprintf(gOutput, "%" PRIu32, uint32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
PoisonOutput();
sprintf(output, "%" PRIx32, uint32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a"));
sprintf(gOutput, "%" PRIx32, uint32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIX32, uint32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCD"));
sprintf(gOutput, "%" PRIX32, uint32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
}
static void
TestPrintUnsigned64()
{
PoisonOutput();
sprintf(output, "%" PRIo64, uint64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242424242"));
sprintf(gOutput, "%" PRIo64, uint64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
PoisonOutput();
sprintf(output, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(output, "17171717171717171717"));
sprintf(gOutput, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
PoisonOutput();
sprintf(output, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a"));
sprintf(gOutput, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCDCDCDCD"));
sprintf(gOutput, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
}
static void
@ -337,80 +338,81 @@ static void
TestPrintUnsignedLeast8()
{
PoisonOutput();
sprintf(output, "%" PRIoLEAST8, uint_least8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIoLEAST8, uint_least8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
PoisonOutput();
sprintf(output, "%" PRIuLEAST8, uint_least8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(output, "17"));
sprintf(gOutput, "%" PRIuLEAST8, uint_least8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
PoisonOutput();
sprintf(output, "%" PRIxLEAST8, uint_least8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a"));
sprintf(gOutput, "%" PRIxLEAST8, uint_least8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
PoisonOutput();
sprintf(output, "%" PRIXLEAST8, uint_least8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CD"));
sprintf(gOutput, "%" PRIXLEAST8, uint_least8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
}
static void
TestPrintUnsignedLeast16()
{
PoisonOutput();
sprintf(output, "%" PRIoLEAST16, uint_least16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(output, "4242"));
sprintf(gOutput, "%" PRIoLEAST16, uint_least16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
PoisonOutput();
sprintf(output, "%" PRIuLEAST16, uint_least16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(output, "1717"));
sprintf(gOutput, "%" PRIuLEAST16, uint_least16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
PoisonOutput();
sprintf(output, "%" PRIxLEAST16, uint_least16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a"));
sprintf(gOutput, "%" PRIxLEAST16, uint_least16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXLEAST16, uint_least16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCD"));
sprintf(gOutput, "%" PRIXLEAST16, uint_least16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
}
static void
TestPrintUnsignedLeast32()
{
PoisonOutput();
sprintf(output, "%" PRIoLEAST32, uint_least32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242"));
sprintf(gOutput, "%" PRIoLEAST32, uint_least32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
PoisonOutput();
sprintf(output, "%" PRIuLEAST32, uint_least32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(output, "171717"));
sprintf(gOutput, "%" PRIuLEAST32, uint_least32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
PoisonOutput();
sprintf(output, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a"));
sprintf(gOutput, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCD"));
sprintf(gOutput, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
}
static void
TestPrintUnsignedLeast64()
{
PoisonOutput();
sprintf(output, "%" PRIoLEAST64, uint_least64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242424242"));
sprintf(gOutput, "%" PRIoLEAST64, uint_least64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
PoisonOutput();
sprintf(output, "%" PRIuLEAST64, uint_least64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(output, "17171717171717171717"));
sprintf(gOutput, "%" PRIuLEAST64,
uint_least64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
PoisonOutput();
sprintf(output, "%" PRIxLEAST64, uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a"));
sprintf(gOutput, "%" PRIxLEAST64, uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXLEAST64, uint_least64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCDCDCDCD"));
sprintf(gOutput, "%" PRIXLEAST64, uint_least64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
}
static void
@ -426,80 +428,81 @@ static void
TestPrintUnsignedFast8()
{
PoisonOutput();
sprintf(output, "%" PRIoFAST8, uint_fast8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(output, "42"));
sprintf(gOutput, "%" PRIoFAST8, uint_fast8_t(042));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
PoisonOutput();
sprintf(output, "%" PRIuFAST8, uint_fast8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(output, "17"));
sprintf(gOutput, "%" PRIuFAST8, uint_fast8_t(17));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
PoisonOutput();
sprintf(output, "%" PRIxFAST8, uint_fast8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a"));
sprintf(gOutput, "%" PRIxFAST8, uint_fast8_t(0x2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
PoisonOutput();
sprintf(output, "%" PRIXFAST8, uint_fast8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CD"));
sprintf(gOutput, "%" PRIXFAST8, uint_fast8_t(0xCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
}
static void
TestPrintUnsignedFast16()
{
PoisonOutput();
sprintf(output, "%" PRIoFAST16, uint_fast16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(output, "4242"));
sprintf(gOutput, "%" PRIoFAST16, uint_fast16_t(04242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
PoisonOutput();
sprintf(output, "%" PRIuFAST16, uint_fast16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(output, "1717"));
sprintf(gOutput, "%" PRIuFAST16, uint_fast16_t(1717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
PoisonOutput();
sprintf(output, "%" PRIxFAST16, uint_fast16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a"));
sprintf(gOutput, "%" PRIxFAST16, uint_fast16_t(0x2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXFAST16, uint_fast16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCD"));
sprintf(gOutput, "%" PRIXFAST16, uint_fast16_t(0xCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
}
static void
TestPrintUnsignedFast32()
{
PoisonOutput();
sprintf(output, "%" PRIoFAST32, uint_fast32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242"));
sprintf(gOutput, "%" PRIoFAST32, uint_fast32_t(0424242));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
PoisonOutput();
sprintf(output, "%" PRIuFAST32, uint_fast32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(output, "171717"));
sprintf(gOutput, "%" PRIuFAST32, uint_fast32_t(171717));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
PoisonOutput();
sprintf(output, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a"));
sprintf(gOutput, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCD"));
sprintf(gOutput, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
}
static void
TestPrintUnsignedFast64()
{
PoisonOutput();
sprintf(output, "%" PRIoFAST64, uint_fast64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(output, "424242424242"));
sprintf(gOutput, "%" PRIoFAST64, uint_fast64_t(UINT64_C(0424242424242)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
PoisonOutput();
sprintf(output, "%" PRIuFAST64, uint_fast64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(output, "17171717171717171717"));
sprintf(gOutput, "%" PRIuFAST64,
uint_fast64_t(UINT64_C(17171717171717171717)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
PoisonOutput();
sprintf(output, "%" PRIxFAST64, uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a"));
sprintf(gOutput, "%" PRIxFAST64, uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
PoisonOutput();
sprintf(output, "%" PRIXFAST64, uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(output, "CDCDCDCDCDCD"));
sprintf(gOutput, "%" PRIXFAST64, uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
}
static void
@ -515,40 +518,40 @@ static void
TestPrintUnsignedMax()
{
PoisonOutput();
sprintf(output, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(output, "14220563454333534"));
sprintf(gOutput, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "14220563454333534"));
PoisonOutput();
sprintf(output, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(output, "325719232983"));
sprintf(gOutput, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
PoisonOutput();
sprintf(output, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873)));
MOZ_RELEASE_ASSERT(!strcmp(output, "4c337ca791"));
sprintf(gOutput, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c337ca791"));
PoisonOutput();
sprintf(output, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523)));
MOZ_RELEASE_ASSERT(!strcmp(output, "33DD03D75A323"));
sprintf(gOutput, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "33DD03D75A323"));
}
static void
TestPrintUnsignedPtr()
{
PoisonOutput();
sprintf(output, "%" PRIoPTR, uintptr_t(reinterpret_cast<void*>(12345678)));
MOZ_RELEASE_ASSERT(!strcmp(output, "57060516"));
sprintf(gOutput, "%" PRIoPTR, uintptr_t(reinterpret_cast<void*>(12345678)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "57060516"));
PoisonOutput();
sprintf(output, "%" PRIuPTR, uintptr_t(reinterpret_cast<void*>(87654321)));
MOZ_RELEASE_ASSERT(!strcmp(output, "87654321"));
sprintf(gOutput, "%" PRIuPTR, uintptr_t(reinterpret_cast<void*>(87654321)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
PoisonOutput();
sprintf(output, "%" PRIxPTR, uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
MOZ_RELEASE_ASSERT(!strcmp(output, "4c3a791"));
sprintf(gOutput, "%" PRIxPTR, uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c3a791"));
PoisonOutput();
sprintf(output, "%" PRIXPTR, uintptr_t(reinterpret_cast<void*>(0xF328DB)));
MOZ_RELEASE_ASSERT(!strcmp(output, "F328DB"));
sprintf(gOutput, "%" PRIXPTR, uintptr_t(reinterpret_cast<void*>(0xF328DB)));
MOZ_RELEASE_ASSERT(!strcmp(gOutput, "F328DB"));
}
static void
@ -607,24 +610,25 @@ TestPrint()
template<typename T>
union Input
{
T i;
unsigned char pun[16];
T mI;
unsigned char mPun[16];
};
template<typename T>
static void
PoisonInput(Input<T>& input)
PoisonInput(Input<T>& aInput)
{
memset(input.pun, 0xDA, sizeof(input.pun));
memset(aInput.mPun, 0xDA, sizeof(aInput.mPun));
}
template<typename T>
static bool
ExtraBitsUntouched(const Input<T>& input)
ExtraBitsUntouched(const Input<T>& aInput)
{
for (size_t i = sizeof(input.i); i < sizeof(input); i++) {
if (input.pun[i] != 0xDA)
for (size_t i = sizeof(aInput.mI); i < sizeof(aInput); i++) {
if (aInput.mPun[i] != 0xDA) {
return false;
}
}
return true;

View File

@ -24,6 +24,8 @@ static_assert(MOZ_ARGS_AFTER_2(a, b, 3) == 3,
static_assert(MOZ_ARG_1(10, 20, 30) == 10, "");
static_assert(MOZ_ARG_2(10, 20, 30) == 20, "");
int main()
int
main()
{
return 0;
}

View File

@ -21,11 +21,15 @@ static_assert(test2_10 == 15 && test2_20 == 25, "");
#define HELPER_IDENTITY_COMMA(k1, k2, x) k1, k2, x,
int main()
int
main()
{
const int a[] = { MOZ_FOR_EACH(HELPER_IDENTITY_COMMA, (1, 2,), (10, 20, 30)) };
const int a[] = {
MOZ_FOR_EACH(HELPER_IDENTITY_COMMA, (1, 2,), (10, 20, 30))
};
MOZ_RELEASE_ASSERT(a[0] == 1 && a[1] == 2 && a[2] == 10 &&
a[3] == 1 && a[4] == 2 && a[5] == 20 &&
a[6] == 1 && a[7] == 2 && a[8] == 30,
"MOZ_FOR_EACH args enumerated in incorrect order");
return 0;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -29,20 +30,20 @@ INSTANTIATE(int, int, prim1, 2 * sizeof(int));
INSTANTIATE(int, long, prim2, 2 * sizeof(long));
struct EmptyClass { EmptyClass(int) {} };
struct NonEmpty { char c; NonEmpty(int) {} };
struct NonEmpty { char mC; NonEmpty(int) {} };
INSTANTIATE(int, EmptyClass, both1, sizeof(int));
INSTANTIATE(int, NonEmpty, both2, 2 * sizeof(int));
INSTANTIATE(EmptyClass, NonEmpty, both3, 1);
struct A { char dummy; A(int) {} };
struct B : A { B(int i) : A(i) {} };
struct B : A { B(int aI) : A(aI) {} };
INSTANTIATE(A, A, class1, 2);
INSTANTIATE(A, B, class2, 2);
INSTANTIATE(A, EmptyClass, class3, 1);
struct OtherEmpty : EmptyClass { OtherEmpty(int i) : EmptyClass(i) {} };
struct OtherEmpty : EmptyClass { OtherEmpty(int aI) : EmptyClass(aI) {} };
// C++11 requires distinct objects of the same type, within the same "most
// derived object", to have different addresses. Pair allocates its elements as
@ -58,4 +59,5 @@ struct OtherEmpty : EmptyClass { OtherEmpty(int i) : EmptyClass(i) {} };
int
main()
{
return 0;
}

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/.
@ -159,7 +159,7 @@
#define RETURN_INSTR 0xd65f03c0 /* ret */
#elif defined __ia64
struct ia64_instr { uint32_t i[4]; };
struct ia64_instr { uint32_t mI[4]; };
static const ia64_instr _return_instr =
{{ 0x00000011, 0x00000001, 0x80000200, 0x00840008 }}; /* br.ret.sptk.many b0 */
@ -179,18 +179,20 @@ static const ia64_instr _return_instr =
#ifdef _WIN32
// Uses of this function deliberately leak the string.
static LPSTR
StrW32Error(DWORD errcode)
StrW32Error(DWORD aErrcode)
{
LPSTR errmsg;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
nullptr, aErrcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&errmsg, 0, nullptr);
// FormatMessage puts an unwanted newline at the end of the string
size_t n = strlen(errmsg)-1;
while (errmsg[n] == '\r' || errmsg[n] == '\n') n--;
while (errmsg[n] == '\r' || errmsg[n] == '\n') {
n--;
}
errmsg[n+1] = '\0';
return errmsg;
}
@ -206,33 +208,29 @@ PageSize()
return sInfo_.dwAllocationGranularity;
}
static void *
ReserveRegion(uintptr_t request, bool accessible)
static void*
ReserveRegion(uintptr_t aRequest, bool aAccessible)
{
return VirtualAlloc((void *)request, PageSize(),
accessible ? MEM_RESERVE|MEM_COMMIT : MEM_RESERVE,
accessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS);
return VirtualAlloc((void*)aRequest, PageSize(),
aAccessible ? MEM_RESERVE|MEM_COMMIT : MEM_RESERVE,
aAccessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS);
}
static void
ReleaseRegion(void *page)
ReleaseRegion(void* aPage)
{
VirtualFree(page, PageSize(), MEM_RELEASE);
VirtualFree(aPage, PageSize(), MEM_RELEASE);
}
static bool
ProbeRegion(uintptr_t page)
ProbeRegion(uintptr_t aPage)
{
if (page >= (uintptr_t)sInfo_.lpMaximumApplicationAddress &&
page + PageSize() >= (uintptr_t)sInfo_.lpMaximumApplicationAddress) {
return true;
} else {
return false;
}
return aPage >= (uintptr_t)sInfo_.lpMaximumApplicationAddress &&
aPage + PageSize() >= (uintptr_t)sInfo_.lpMaximumApplicationAddress;
}
static bool
MakeRegionExecutable(void *)
MakeRegionExecutable(void*)
{
return false;
}
@ -244,42 +242,38 @@ MakeRegionExecutable(void *)
#define LastErrMsg() (strerror(errno))
static unsigned long unixPageSize;
static unsigned long gUnixPageSize;
static inline unsigned long
PageSize()
{
return unixPageSize;
return gUnixPageSize;
}
static void *
ReserveRegion(uintptr_t request, bool accessible)
static void*
ReserveRegion(uintptr_t aRequest, bool aAccessible)
{
return mmap(reinterpret_cast<void*>(request), PageSize(),
accessible ? PROT_READ|PROT_WRITE : PROT_NONE,
return mmap(reinterpret_cast<void*>(aRequest), PageSize(),
aAccessible ? PROT_READ|PROT_WRITE : PROT_NONE,
MAP_PRIVATE|MAP_ANON, -1, 0);
}
static void
ReleaseRegion(void *page)
ReleaseRegion(void* aPage)
{
munmap(page, PageSize());
munmap(aPage, PageSize());
}
static bool
ProbeRegion(uintptr_t page)
ProbeRegion(uintptr_t aPage)
{
if (madvise(reinterpret_cast<void*>(page), PageSize(), MADV_NORMAL)) {
return true;
} else {
return false;
}
return !!madvise(reinterpret_cast<void*>(aPage), PageSize(), MADV_NORMAL);
}
static int
MakeRegionExecutable(void *page)
MakeRegionExecutable(void* aPage)
{
return mprotect((caddr_t)page, PageSize(), PROT_READ|PROT_WRITE|PROT_EXEC);
return mprotect((caddr_t)aPage, PageSize(), PROT_READ|PROT_WRITE|PROT_EXEC);
}
#endif
@ -296,48 +290,51 @@ ReservePoisonArea()
~uintptr_t(PageSize()-1));
printf("INFO | poison area assumed at 0x%.*" PRIxPTR "\n", SIZxPTR, result);
return result;
} else {
// First see if we can allocate the preferred poison address from the OS.
uintptr_t candidate = (0xF0DEAFFF & ~(PageSize()-1));
void *result = ReserveRegion(candidate, false);
if (result == (void *)candidate) {
// success - inaccessible page allocated
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (preferred addr)\n", SIZxPTR, (uintptr_t)result);
return candidate;
}
// That didn't work, so see if the preferred address is within a range
// of permanently inacessible memory.
if (ProbeRegion(candidate)) {
// success - selected page cannot be usable memory
if (result != MAP_FAILED)
ReleaseRegion(result);
printf("INFO | poison area assumed at 0x%.*" PRIxPTR
" (preferred addr)\n", SIZxPTR, candidate);
return candidate;
}
// The preferred address is already in use. Did the OS give us a
// consolation prize?
if (result != MAP_FAILED) {
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (consolation prize)\n", SIZxPTR, (uintptr_t)result);
return (uintptr_t)result;
}
// It didn't, so try to allocate again, without any constraint on
// the address.
result = ReserveRegion(0, false);
if (result != MAP_FAILED) {
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (fallback)\n", SIZxPTR, (uintptr_t)result);
return (uintptr_t)result;
}
printf("ERROR | no usable poison area found\n");
return 0;
}
// First see if we can allocate the preferred poison address from the OS.
uintptr_t candidate = (0xF0DEAFFF & ~(PageSize() - 1));
void* result = ReserveRegion(candidate, false);
if (result == reinterpret_cast<void*>(candidate)) {
// success - inaccessible page allocated
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (preferred addr)\n", SIZxPTR, reinterpret_cast<uintptr_t>(result));
return candidate;
}
// That didn't work, so see if the preferred address is within a range
// of permanently inacessible memory.
if (ProbeRegion(candidate)) {
// success - selected page cannot be usable memory
if (result != MAP_FAILED) {
ReleaseRegion(result);
}
printf("INFO | poison area assumed at 0x%.*" PRIxPTR
" (preferred addr)\n", SIZxPTR, candidate);
return candidate;
}
// The preferred address is already in use. Did the OS give us a
// consolation prize?
if (result != MAP_FAILED) {
uintptr_t ures = reinterpret_cast<uintptr_t>(result);
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (consolation prize)\n", SIZxPTR, ures);
return ures;
}
// It didn't, so try to allocate again, without any constraint on
// the address.
result = ReserveRegion(0, false);
if (result != MAP_FAILED) {
uintptr_t ures = reinterpret_cast<uintptr_t>(result);
printf("INFO | poison area allocated at 0x%.*" PRIxPTR
" (fallback)\n", SIZxPTR, ures);
return ures;
}
printf("ERROR | no usable poison area found\n");
return 0;
}
/* The "positive control" area confirms that we can allocate a page with the
@ -347,7 +344,7 @@ static uintptr_t
ReservePositiveControl()
{
void *result = ReserveRegion(0, false);
void* result = ReserveRegion(0, false);
if (result == MAP_FAILED) {
printf("ERROR | allocating positive control | %s\n", LastErrMsg());
return 0;
@ -363,17 +360,20 @@ ReservePositiveControl()
static uintptr_t
ReserveNegativeControl()
{
void *result = ReserveRegion(0, true);
void* result = ReserveRegion(0, true);
if (result == MAP_FAILED) {
printf("ERROR | allocating negative control | %s\n", LastErrMsg());
return 0;
}
// Fill the page with return instructions.
RETURN_INSTR_TYPE *p = (RETURN_INSTR_TYPE *)result;
RETURN_INSTR_TYPE *limit = (RETURN_INSTR_TYPE *)(((char *)result) + PageSize());
while (p < limit)
RETURN_INSTR_TYPE* p = reinterpret_cast<RETURN_INSTR_TYPE*>(result);
RETURN_INSTR_TYPE* limit =
reinterpret_cast<RETURN_INSTR_TYPE*>(
reinterpret_cast<char*>(result) + PageSize());
while (p < limit) {
*p++ = RETURN_INSTR;
}
// Now mark it executable as well as readable and writable.
// (mmap(PROT_EXEC) may fail when applied to anonymous memory.)
@ -389,35 +389,36 @@ ReserveNegativeControl()
}
static void
JumpTo(uintptr_t opaddr)
JumpTo(uintptr_t aOpaddr)
{
#ifdef __ia64
struct func_call {
uintptr_t func;
uintptr_t gp;
} call = { opaddr, };
struct func_call
{
uintptr_t mFunc;
uintptr_t mGp;
} call = { aOpaddr, };
((void (*)())&call)();
#else
((void (*)())opaddr)();
((void (*)())aOpaddr)();
#endif
}
#ifdef _WIN32
static BOOL
IsBadExecPtr(uintptr_t ptr)
IsBadExecPtr(uintptr_t aPtr)
{
BOOL ret = false;
#if defined(_MSC_VER) && !defined(__clang__)
__try {
JumpTo(ptr);
JumpTo(aPtr);
} __except (EXCEPTION_EXECUTE_HANDLER) {
ret = true;
}
#else
printf("INFO | exec test not supported on MinGW or clang-cl builds\n");
// We do our best
ret = IsBadReadPtr((const void*)ptr, 1);
ret = IsBadReadPtr((const void*)aPtr, 1);
#endif
return ret;
}
@ -425,9 +426,9 @@ IsBadExecPtr(uintptr_t ptr)
/* Test each page. */
static bool
TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed)
TestPage(const char* aPageLabel, uintptr_t aPageAddr, int aShouldSucceed)
{
const char *oplabel;
const char* oplabel;
uintptr_t opaddr;
bool failed = false;
@ -435,9 +436,9 @@ TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed)
switch (test) {
// The execute test must be done before the write test, because the
// write test will clobber memory at the target address.
case 0: oplabel = "reading"; opaddr = pageaddr + PageSize()/2 - 1; break;
case 1: oplabel = "executing"; opaddr = pageaddr + PageSize()/2; break;
case 2: oplabel = "writing"; opaddr = pageaddr + PageSize()/2 - 1; break;
case 0: oplabel = "reading"; opaddr = aPageAddr + PageSize()/2 - 1; break;
case 1: oplabel = "executing"; opaddr = aPageAddr + PageSize()/2; break;
case 2: oplabel = "writing"; opaddr = aPageAddr + PageSize()/2 - 1; break;
default: abort();
}
@ -452,33 +453,33 @@ TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed)
}
if (badptr) {
if (should_succeed) {
printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel);
if (aShouldSucceed) {
printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, aPageLabel);
failed = true;
} else {
printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
printf("TEST-PASS | %s %s\n", oplabel, aPageLabel);
}
} else {
// if control reaches this point the probe succeeded
if (should_succeed) {
printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
if (aShouldSucceed) {
printf("TEST-PASS | %s %s\n", oplabel, aPageLabel);
} else {
printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel);
printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, aPageLabel);
failed = true;
}
}
#else
pid_t pid = fork();
if (pid == -1) {
printf("ERROR | %s %s | fork=%s\n", oplabel, pagelabel,
printf("ERROR | %s %s | fork=%s\n", oplabel, aPageLabel,
LastErrMsg());
exit(2);
} else if (pid == 0) {
volatile unsigned char scratch;
switch (test) {
case 0: scratch = *(volatile unsigned char *)opaddr; break;
case 0: scratch = *(volatile unsigned char*)opaddr; break;
case 1: JumpTo(opaddr); break;
case 2: *(volatile unsigned char *)opaddr = 0; break;
case 2: *(volatile unsigned char*)opaddr = 0; break;
default: abort();
}
(void)scratch;
@ -486,35 +487,35 @@ TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed)
} else {
int status;
if (waitpid(pid, &status, 0) != pid) {
printf("ERROR | %s %s | wait=%s\n", oplabel, pagelabel,
printf("ERROR | %s %s | wait=%s\n", oplabel, aPageLabel,
LastErrMsg());
exit(2);
}
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
if (should_succeed) {
printf("TEST-PASS | %s %s\n", oplabel, pagelabel);
if (aShouldSucceed) {
printf("TEST-PASS | %s %s\n", oplabel, aPageLabel);
} else {
printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected successful exit\n",
oplabel, pagelabel);
oplabel, aPageLabel);
failed = true;
}
} else if (WIFEXITED(status)) {
printf("ERROR | %s %s | unexpected exit code %d\n",
oplabel, pagelabel, WEXITSTATUS(status));
oplabel, aPageLabel, WEXITSTATUS(status));
exit(2);
} else if (WIFSIGNALED(status)) {
if (should_succeed) {
if (aShouldSucceed) {
printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected signal %d\n",
oplabel, pagelabel, WTERMSIG(status));
oplabel, aPageLabel, WTERMSIG(status));
failed = true;
} else {
printf("TEST-PASS | %s %s | signal %d (as expected)\n",
oplabel, pagelabel, WTERMSIG(status));
oplabel, aPageLabel, WTERMSIG(status));
}
} else {
printf("ERROR | %s %s | unexpected exit status %d\n",
oplabel, pagelabel, status);
oplabel, aPageLabel, status);
exit(2);
}
}
@ -529,15 +530,16 @@ main()
#ifdef _WIN32
GetSystemInfo(&sInfo_);
#else
unixPageSize = sysconf(_SC_PAGESIZE);
gUnixPageSize = sysconf(_SC_PAGESIZE);
#endif
uintptr_t ncontrol = ReserveNegativeControl();
uintptr_t pcontrol = ReservePositiveControl();
uintptr_t poison = ReservePoisonArea();
if (!ncontrol || !pcontrol || !poison)
if (!ncontrol || !pcontrol || !poison) {
return 2;
}
bool failed = false;
failed |= TestPage("negative control", ncontrol, 1);

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -10,110 +11,117 @@ using mozilla::RollingMean;
class MyClass
{
public:
uint32_t value;
public:
uint32_t mValue;
explicit MyClass(uint32_t val = 0) : value(val) {
}
explicit MyClass(uint32_t aValue = 0) : mValue(aValue) { }
bool operator==(const MyClass& other) const {
return value == other.value;
}
bool operator==(const MyClass& aOther) const
{
return mValue == aOther.mValue;
}
MyClass operator+(const MyClass& other) const {
return MyClass(value + other.value);
}
MyClass operator+(const MyClass& aOther) const
{
return MyClass(mValue + aOther.mValue);
}
MyClass operator-(const MyClass& other) const {
return MyClass(value - other.value);
}
MyClass operator-(const MyClass& aOther) const
{
return MyClass(mValue - aOther.mValue);
}
MyClass operator/(uint32_t div) const {
return MyClass(value / div);
}
MyClass operator/(uint32_t aDiv) const
{
return MyClass(mValue / aDiv);
}
};
class RollingMeanSuite
{
public:
RollingMeanSuite()
{ }
public:
RollingMeanSuite() { }
void runTests() {
testZero();
testClear();
testRolling();
testClass();
testMove();
}
void runTests() {
testZero();
testClear();
testRolling();
testClass();
testMove();
}
private:
void testZero() {
RollingMean<uint32_t, uint64_t> mean(3);
MOZ_RELEASE_ASSERT(mean.empty());
}
private:
void testZero()
{
RollingMean<uint32_t, uint64_t> mean(3);
MOZ_RELEASE_ASSERT(mean.empty());
}
void testClear() {
RollingMean<uint32_t, uint64_t> mean(3);
void testClear()
{
RollingMean<uint32_t, uint64_t> mean(3);
mean.insert(4);
MOZ_RELEASE_ASSERT(mean.mean() == 4);
mean.insert(4);
MOZ_RELEASE_ASSERT(mean.mean() == 4);
mean.clear();
MOZ_RELEASE_ASSERT(mean.empty());
mean.clear();
MOZ_RELEASE_ASSERT(mean.empty());
mean.insert(3);
MOZ_RELEASE_ASSERT(mean.mean() == 3);
}
mean.insert(3);
MOZ_RELEASE_ASSERT(mean.mean() == 3);
}
void testRolling() {
RollingMean<uint32_t, uint64_t> mean(3);
void testRolling()
{
RollingMean<uint32_t, uint64_t> mean(3);
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 10);
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 10);
mean.insert(20);
MOZ_RELEASE_ASSERT(mean.mean() == 15);
mean.insert(20);
MOZ_RELEASE_ASSERT(mean.mean() == 15);
mean.insert(35);
MOZ_RELEASE_ASSERT(mean.mean() == 21);
mean.insert(35);
MOZ_RELEASE_ASSERT(mean.mean() == 21);
mean.insert(5);
MOZ_RELEASE_ASSERT(mean.mean() == 20);
mean.insert(5);
MOZ_RELEASE_ASSERT(mean.mean() == 20);
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 16);
}
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 16);
}
void testClass() {
RollingMean<MyClass, MyClass> mean(3);
void testClass()
{
RollingMean<MyClass, MyClass> mean(3);
mean.insert(MyClass(4));
MOZ_RELEASE_ASSERT(mean.mean() == MyClass(4));
mean.insert(MyClass(4));
MOZ_RELEASE_ASSERT(mean.mean() == MyClass(4));
mean.clear();
MOZ_RELEASE_ASSERT(mean.empty());
}
mean.clear();
MOZ_RELEASE_ASSERT(mean.empty());
}
void testMove() {
RollingMean<uint32_t, uint64_t> mean(3);
mean = RollingMean<uint32_t, uint64_t>(4);
MOZ_RELEASE_ASSERT(mean.maxValues() == 4);
void testMove()
{
RollingMean<uint32_t, uint64_t> mean(3);
mean = RollingMean<uint32_t, uint64_t>(4);
MOZ_RELEASE_ASSERT(mean.maxValues() == 4);
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 10);
mean = RollingMean<uint32_t, uint64_t>(3);
mean.insert(30);
mean.insert(40);
mean.insert(50);
mean.insert(60);
MOZ_RELEASE_ASSERT(mean.mean() == 50);
}
mean.insert(10);
MOZ_RELEASE_ASSERT(mean.mean() == 10);
mean = RollingMean<uint32_t, uint64_t>(3);
mean.insert(30);
mean.insert(40);
mean.insert(50);
mean.insert(60);
MOZ_RELEASE_ASSERT(mean.mean() == 50);
}
};
int main()
int
main()
{
RollingMeanSuite suite;
suite.runTests();

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -7,7 +9,7 @@
using mozilla::SHA1Sum;
static unsigned int testV[1024] = {
static unsigned int gTestV[1024] = {
0x048edc1a, 0x4345588c, 0x0ef03cbf, 0x1d6438f5, 0x094e0a1e, 0x68535f60,
0x14e8c927, 0x60190043, 0x5d640ab7, 0x73dc7c62, 0x364223f9, 0x47320292,
0x3924cae0, 0x5f6b26d3, 0x5efa04ef, 0x7aab361e, 0x2773b1aa, 0x1631b07d,
@ -186,12 +188,13 @@ main()
{
SHA1Sum sum;
SHA1Sum::Hash hash;
sum.update(reinterpret_cast<const uint8_t*>(testV), sizeof(testV));
sum.update(reinterpret_cast<const uint8_t*>(gTestV), sizeof(gTestV));
sum.finish(hash);
static const uint8_t expected[20] =
{ 0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81 };
static const uint8_t expected[20] = {
0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81
};
static_assert(sizeof(expected) == sizeof(SHA1Sum::Hash),
"expected-data size should be the same as the actual hash "

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -22,67 +23,107 @@ using mozilla::MakeSigned;
using mozilla::MakeUnsigned;
using mozilla::RemoveExtent;
static_assert(!IsArray<bool>::value, "bool not an array");
static_assert(IsArray<bool[]>::value, "bool[] is an array");
static_assert(IsArray<bool[5]>::value, "bool[5] is an array");
static_assert(!IsArray<bool>::value,
"bool not an array");
static_assert(IsArray<bool[]>::value,
"bool[] is an array");
static_assert(IsArray<bool[5]>::value,
"bool[5] is an array");
static_assert(!IsLvalueReference<bool>::value, "bool not an lvalue reference");
static_assert(!IsLvalueReference<bool*>::value, "bool* not an lvalue reference");
static_assert(IsLvalueReference<bool&>::value, "bool& is an lvalue reference");
static_assert(!IsLvalueReference<bool&&>::value, "bool&& not an lvalue reference");
static_assert(!IsLvalueReference<bool>::value,
"bool not an lvalue reference");
static_assert(!IsLvalueReference<bool*>::value,
"bool* not an lvalue reference");
static_assert(IsLvalueReference<bool&>::value,
"bool& is an lvalue reference");
static_assert(!IsLvalueReference<bool&&>::value,
"bool&& not an lvalue reference");
static_assert(!IsLvalueReference<void>::value, "void not an lvalue reference");
static_assert(!IsLvalueReference<void*>::value, "void* not an lvalue reference");
static_assert(!IsLvalueReference<void>::value,
"void not an lvalue reference");
static_assert(!IsLvalueReference<void*>::value,
"void* not an lvalue reference");
static_assert(!IsLvalueReference<int>::value, "int not an lvalue reference");
static_assert(!IsLvalueReference<int*>::value, "int* not an lvalue reference");
static_assert(IsLvalueReference<int&>::value, "int& is an lvalue reference");
static_assert(!IsLvalueReference<int&&>::value, "int&& not an lvalue reference");
static_assert(!IsLvalueReference<int>::value,
"int not an lvalue reference");
static_assert(!IsLvalueReference<int*>::value,
"int* not an lvalue reference");
static_assert(IsLvalueReference<int&>::value,
"int& is an lvalue reference");
static_assert(!IsLvalueReference<int&&>::value,
"int&& not an lvalue reference");
static_assert(!IsRvalueReference<bool>::value, "bool not an rvalue reference");
static_assert(!IsRvalueReference<bool*>::value, "bool* not an rvalue reference");
static_assert(!IsRvalueReference<bool&>::value, "bool& not an rvalue reference");
static_assert(IsRvalueReference<bool&&>::value, "bool&& is an rvalue reference");
static_assert(!IsRvalueReference<bool>::value,
"bool not an rvalue reference");
static_assert(!IsRvalueReference<bool*>::value,
"bool* not an rvalue reference");
static_assert(!IsRvalueReference<bool&>::value,
"bool& not an rvalue reference");
static_assert(IsRvalueReference<bool&&>::value,
"bool&& is an rvalue reference");
static_assert(!IsRvalueReference<void>::value, "void not an rvalue reference");
static_assert(!IsRvalueReference<void*>::value, "void* not an rvalue reference");
static_assert(!IsRvalueReference<void>::value,
"void not an rvalue reference");
static_assert(!IsRvalueReference<void*>::value,
"void* not an rvalue reference");
static_assert(!IsRvalueReference<int>::value, "int not an rvalue reference");
static_assert(!IsRvalueReference<int*>::value, "int* not an rvalue reference");
static_assert(!IsRvalueReference<int&>::value, "int& not an rvalue reference");
static_assert(IsRvalueReference<int&&>::value, "int&& is an rvalue reference");
static_assert(!IsRvalueReference<int>::value,
"int not an rvalue reference");
static_assert(!IsRvalueReference<int*>::value,
"int* not an rvalue reference");
static_assert(!IsRvalueReference<int&>::value,
"int& not an rvalue reference");
static_assert(IsRvalueReference<int&&>::value,
"int&& is an rvalue reference");
static_assert(!IsReference<bool>::value, "bool not a reference");
static_assert(!IsReference<bool*>::value, "bool* not a reference");
static_assert(IsReference<bool&>::value, "bool& is a reference");
static_assert(IsReference<bool&&>::value, "bool&& is a reference");
static_assert(!IsReference<bool>::value,
"bool not a reference");
static_assert(!IsReference<bool*>::value,
"bool* not a reference");
static_assert(IsReference<bool&>::value,
"bool& is a reference");
static_assert(IsReference<bool&&>::value,
"bool&& is a reference");
static_assert(!IsReference<void>::value, "void not a reference");
static_assert(!IsReference<void*>::value, "void* not a reference");
static_assert(!IsReference<void>::value,
"void not a reference");
static_assert(!IsReference<void*>::value,
"void* not a reference");
static_assert(!IsReference<int>::value, "int not a reference");
static_assert(!IsReference<int*>::value, "int* not a reference");
static_assert(IsReference<int&>::value, "int& is a reference");
static_assert(IsReference<int&&>::value, "int&& is a reference");
static_assert(!IsReference<int>::value,
"int not a reference");
static_assert(!IsReference<int*>::value,
"int* not a reference");
static_assert(IsReference<int&>::value,
"int& is a reference");
static_assert(IsReference<int&&>::value,
"int&& is a reference");
struct S1 {};
union U1 { int x; };
union U1 { int mX; };
static_assert(!IsClass<int>::value, "int isn't a class");
static_assert(IsClass<const S1>::value, "S is a class");
static_assert(!IsClass<U1>::value, "U isn't a class");
static_assert(!IsClass<int>::value,
"int isn't a class");
static_assert(IsClass<const S1>::value,
"S is a class");
static_assert(!IsClass<U1>::value,
"U isn't a class");
static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty");
static_assert(!mozilla::IsEmpty<bool[5]>::value, "not a class => not empty");
static_assert(!mozilla::IsEmpty<int>::value,
"not a class => not empty");
static_assert(!mozilla::IsEmpty<bool[5]>::value,
"not a class => not empty");
static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty");
static_assert(!mozilla::IsEmpty<U1>::value,
"not a class => not empty");
struct E1 {};
struct E2 { int : 0; };
struct E3 : E1 {};
struct E4 : E2 {};
static_assert(IsEmpty<const volatile S1>::value, "S should be empty");
static_assert(IsEmpty<const volatile S1>::value,
"S should be empty");
static_assert(mozilla::IsEmpty<E1>::value &&
mozilla::IsEmpty<E2>::value &&
@ -91,9 +132,10 @@ static_assert(mozilla::IsEmpty<E1>::value &&
"all empty");
union U2 { E1 e1; };
static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty");
static_assert(!mozilla::IsEmpty<U2>::value,
"not a class => not empty");
struct NE1 { int x; };
struct NE1 { int mX; };
struct NE2 : virtual E1 {};
struct NE3 : E2 { virtual ~NE3() {} };
struct NE4 { virtual void f() {} };
@ -104,49 +146,81 @@ static_assert(!mozilla::IsEmpty<NE1>::value &&
!mozilla::IsEmpty<NE4>::value,
"all empty");
static_assert(!IsSigned<bool>::value, "bool shouldn't be signed");
static_assert(IsUnsigned<bool>::value, "bool should be unsigned");
static_assert(!IsSigned<bool>::value,
"bool shouldn't be signed");
static_assert(IsUnsigned<bool>::value,
"bool should be unsigned");
static_assert(!IsSigned<const bool>::value, "const bool shouldn't be signed");
static_assert(IsUnsigned<const bool>::value, "const bool should be unsigned");
static_assert(!IsSigned<const bool>::value,
"const bool shouldn't be signed");
static_assert(IsUnsigned<const bool>::value,
"const bool should be unsigned");
static_assert(!IsSigned<volatile bool>::value, "volatile bool shouldn't be signed");
static_assert(IsUnsigned<volatile bool>::value, "volatile bool should be unsigned");
static_assert(!IsSigned<volatile bool>::value,
"volatile bool shouldn't be signed");
static_assert(IsUnsigned<volatile bool>::value,
"volatile bool should be unsigned");
static_assert(!IsSigned<unsigned char>::value, "unsigned char shouldn't be signed");
static_assert(IsUnsigned<unsigned char>::value, "unsigned char should be unsigned");
static_assert(IsSigned<signed char>::value, "signed char should be signed");
static_assert(!IsUnsigned<signed char>::value, "signed char shouldn't be unsigned");
static_assert(!IsSigned<unsigned char>::value,
"unsigned char shouldn't be signed");
static_assert(IsUnsigned<unsigned char>::value,
"unsigned char should be unsigned");
static_assert(IsSigned<signed char>::value,
"signed char should be signed");
static_assert(!IsUnsigned<signed char>::value,
"signed char shouldn't be unsigned");
static_assert(!IsSigned<unsigned short>::value, "unsigned short shouldn't be signed");
static_assert(IsUnsigned<unsigned short>::value, "unsigned short should be unsigned");
static_assert(IsSigned<short>::value, "short should be signed");
static_assert(!IsUnsigned<short>::value, "short shouldn't be unsigned");
static_assert(!IsSigned<unsigned short>::value,
"unsigned short shouldn't be signed");
static_assert(IsUnsigned<unsigned short>::value,
"unsigned short should be unsigned");
static_assert(IsSigned<short>::value,
"short should be signed");
static_assert(!IsUnsigned<short>::value,
"short shouldn't be unsigned");
static_assert(!IsSigned<unsigned int>::value, "unsigned int shouldn't be signed");
static_assert(IsUnsigned<unsigned int>::value, "unsigned int should be unsigned");
static_assert(IsSigned<int>::value, "int should be signed");
static_assert(!IsUnsigned<int>::value, "int shouldn't be unsigned");
static_assert(!IsSigned<unsigned int>::value,
"unsigned int shouldn't be signed");
static_assert(IsUnsigned<unsigned int>::value,
"unsigned int should be unsigned");
static_assert(IsSigned<int>::value,
"int should be signed");
static_assert(!IsUnsigned<int>::value,
"int shouldn't be unsigned");
static_assert(!IsSigned<unsigned long>::value, "unsigned long shouldn't be signed");
static_assert(IsUnsigned<unsigned long>::value, "unsigned long should be unsigned");
static_assert(IsSigned<long>::value, "long should be signed");
static_assert(!IsUnsigned<long>::value, "long shouldn't be unsigned");
static_assert(!IsSigned<unsigned long>::value,
"unsigned long shouldn't be signed");
static_assert(IsUnsigned<unsigned long>::value,
"unsigned long should be unsigned");
static_assert(IsSigned<long>::value,
"long should be signed");
static_assert(!IsUnsigned<long>::value,
"long shouldn't be unsigned");
static_assert(IsSigned<float>::value, "float should be signed");
static_assert(!IsUnsigned<float>::value, "float shouldn't be unsigned");
static_assert(IsSigned<float>::value,
"float should be signed");
static_assert(!IsUnsigned<float>::value,
"float shouldn't be unsigned");
static_assert(IsSigned<const float>::value, "const float should be signed");
static_assert(!IsUnsigned<const float>::value, "const float shouldn't be unsigned");
static_assert(IsSigned<const float>::value,
"const float should be signed");
static_assert(!IsUnsigned<const float>::value,
"const float shouldn't be unsigned");
static_assert(IsSigned<double>::value, "double should be signed");
static_assert(!IsUnsigned<double>::value, "double shouldn't be unsigned");
static_assert(IsSigned<double>::value,
"double should be signed");
static_assert(!IsUnsigned<double>::value,
"double shouldn't be unsigned");
static_assert(IsSigned<volatile double>::value, "volatile double should be signed");
static_assert(!IsUnsigned<volatile double>::value, "volatile double shouldn't be unsigned");
static_assert(IsSigned<volatile double>::value,
"volatile double should be signed");
static_assert(!IsUnsigned<volatile double>::value,
"volatile double shouldn't be unsigned");
static_assert(IsSigned<long double>::value, "long double should be signed");
static_assert(!IsUnsigned<long double>::value, "long double shouldn't be unsigned");
static_assert(IsSigned<long double>::value,
"long double should be signed");
static_assert(!IsUnsigned<long double>::value,
"long double shouldn't be unsigned");
static_assert(IsSigned<const volatile long double>::value,
"const volatile long double should be signed");
@ -174,13 +248,20 @@ struct D : private B1, private B2 {};
static void
StandardIsBaseOfTests()
{
static_assert((IsBaseOf<B, D>::value) == true, "IsBaseOf fails on diamond");
static_assert((IsBaseOf<const B, D>::value) == true, "IsBaseOf fails on diamond plus constness change");
static_assert((IsBaseOf<B, const D>::value) == true, "IsBaseOf fails on diamond plus constness change");
static_assert((IsBaseOf<B, const B>::value) == true, "IsBaseOf fails on constness change");
static_assert((IsBaseOf<D, B>::value) == false, "IsBaseOf got the direction of inheritance wrong");
static_assert((IsBaseOf<B&, D&>::value) == false, "IsBaseOf should return false on references");
static_assert((IsBaseOf<B[3], D[3]>::value) == false, "IsBaseOf should return false on arrays");
static_assert((IsBaseOf<B, D>::value) == true,
"IsBaseOf fails on diamond");
static_assert((IsBaseOf<const B, D>::value) == true,
"IsBaseOf fails on diamond plus constness change");
static_assert((IsBaseOf<B, const D>::value) == true,
"IsBaseOf fails on diamond plus constness change");
static_assert((IsBaseOf<B, const B>::value) == true,
"IsBaseOf fails on constness change");
static_assert((IsBaseOf<D, B>::value) == false,
"IsBaseOf got the direction of inheritance wrong");
static_assert((IsBaseOf<B&, D&>::value) == false,
"IsBaseOf should return false on references");
static_assert((IsBaseOf<B[3], D[3]>::value) == false,
"IsBaseOf should return false on arrays");
// We fail at the following test. To fix it, we need to specialize IsBaseOf
// for all built-in types.
// static_assert((IsBaseOf<int, int>::value) == false);
@ -199,23 +280,23 @@ static void
TestIsBaseOf()
{
static_assert((IsBaseOf<A, B>::value),
"A is a base of B");
"A is a base of B");
static_assert((!IsBaseOf<B, A>::value),
"B is not a base of A");
"B is not a base of A");
static_assert((IsBaseOf<A, C>::value),
"A is a base of C");
"A is a base of C");
static_assert((!IsBaseOf<C, A>::value),
"C is not a base of A");
"C is not a base of A");
static_assert((IsBaseOf<A, F>::value),
"A is a base of F");
"A is a base of F");
static_assert((!IsBaseOf<F, A>::value),
"F is not a base of A");
"F is not a base of A");
static_assert((!IsBaseOf<A, D>::value),
"A is not a base of D");
"A is not a base of D");
static_assert((!IsBaseOf<D, A>::value),
"D is not a base of A");
"D is not a base of A");
static_assert((IsBaseOf<B, B>::value),
"B is the same as B (and therefore, a base of B)");
"B is the same as B (and therefore, a base of B)");
}
static void
@ -223,27 +304,27 @@ TestIsConvertible()
{
// Pointer type convertibility
static_assert((IsConvertible<A*, A*>::value),
"A* should convert to A*");
"A* should convert to A*");
static_assert((IsConvertible<B*, A*>::value),
"B* should convert to A*");
"B* should convert to A*");
static_assert((!IsConvertible<A*, B*>::value),
"A* shouldn't convert to B*");
"A* shouldn't convert to B*");
static_assert((!IsConvertible<A*, C*>::value),
"A* shouldn't convert to C*");
"A* shouldn't convert to C*");
static_assert((!IsConvertible<A*, D*>::value),
"A* shouldn't convert to unrelated D*");
"A* shouldn't convert to unrelated D*");
static_assert((!IsConvertible<D*, A*>::value),
"D* shouldn't convert to unrelated A*");
"D* shouldn't convert to unrelated A*");
// Instance type convertibility
static_assert((IsConvertible<A, A>::value),
"A is A");
"A is A");
static_assert((IsConvertible<B, A>::value),
"B converts to A");
"B converts to A");
static_assert((!IsConvertible<D, A>::value),
"D and A are unrelated");
"D and A are unrelated");
static_assert((!IsConvertible<A, D>::value),
"A and D are unrelated");
"A and D are unrelated");
// These cases seem to require C++11 support to properly implement them, so
// for now just disable them.
@ -344,4 +425,5 @@ main()
CPlusPlus11IsBaseOf::StandardIsBaseOfTests();
TestIsBaseOf();
TestIsConvertible();
return 0;
}

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -184,56 +186,56 @@ TestTypedEnumBasics()
}
// Op wraps a bitwise binary operator, passed as a char template parameter,
// and applies it to its arguments (t1, t2). For example,
// and applies it to its arguments (aT1, aT2). For example,
//
// Op<'|'>(t1, t2)
// Op<'|'>(aT1, aT2)
//
// is the same as
//
// t1 | t2.
// aT1 | aT2.
//
template<char o, typename T1, typename T2>
auto Op(const T1& t1, const T2& t2)
-> decltype(t1 | t2) // See the static_assert's below --- the return type
// depends solely on the operands type, not on the
// choice of operation.
auto Op(const T1& aT1, const T2& aT2)
-> decltype(aT1 | aT2) // See the static_assert's below --- the return type
// depends solely on the operands type, not on the
// choice of operation.
{
using mozilla::IsSame;
static_assert(IsSame<decltype(t1 | t2), decltype(t1 & t2)>::value,
static_assert(IsSame<decltype(aT1 | aT2), decltype(aT1 & aT2)>::value,
"binary ops should have the same result type");
static_assert(IsSame<decltype(t1 | t2), decltype(t1 ^ t2)>::value,
static_assert(IsSame<decltype(aT1 | aT2), decltype(aT1 ^ aT2)>::value,
"binary ops should have the same result type");
static_assert(o == '|' ||
o == '&' ||
o == '^', "unexpected operator character");
return o == '|' ? t1 | t2
: o == '&' ? t1 & t2
: t1 ^ t2;
return o == '|' ? aT1 | aT2
: o == '&' ? aT1 & aT2
: aT1 ^ aT2;
}
// OpAssign wraps a bitwise binary operator, passed as a char template
// parameter, and applies the corresponding compound-assignment operator to its
// arguments (t1, t2). For example,
// arguments (aT1, aT2). For example,
//
// OpAssign<'|'>(t1, t2)
// OpAssign<'|'>(aT1, aT2)
//
// is the same as
//
// t1 |= t2.
// aT1 |= aT2.
//
template<char o, typename T1, typename T2>
T1& OpAssign(T1& t1, const T2& t2)
T1& OpAssign(T1& aT1, const T2& aT2)
{
static_assert(o == '|' ||
o == '&' ||
o == '^', "unexpected operator character");
switch (o) {
case '|': return t1 |= t2;
case '&': return t1 &= t2;
case '^': return t1 ^= t2;
case '|': return aT1 |= aT2;
case '&': return aT1 &= aT2;
case '^': return aT1 ^= aT2;
default: MOZ_CRASH();
}
}
@ -241,38 +243,39 @@ T1& OpAssign(T1& t1, const T2& t2)
// Tests a single binary bitwise operator, using a single set of three operands.
// The operations tested are:
//
// result = t1 Op t2;
// result Op= t3;
// result = aT1 Op aT2;
// result Op= aT3;
//
// Where Op is the operator specified by the char template parameter 'o' and can
// be any of '|', '&', '^'.
// Where Op is the operator specified by the char template parameter 'o' and
// can be any of '|', '&', '^'.
//
// Note that the operands aT1, aT2, aT3 are intentionally passed with free
// types (separate template parameters for each) because their type may
// actually be different from TypedEnum:
//
// Note that the operands t1, t2, t3 are intentionally passed with free types
// (separate template parameters for each) because their type may actually be
// different from TypedEnum:
// 1) Their type could be CastableTypedEnumResult<TypedEnum> if they are
// the result of a bitwise operation themselves;
// 2) In the non-c++11 legacy path, the type of enum values is also
// different from TypedEnum.
//
template<typename TypedEnum, char o, typename T1, typename T2, typename T3>
void TestBinOp(const T1& t1, const T2& t2, const T3& t3)
void TestBinOp(const T1& aT1, const T2& aT2, const T3& aT3)
{
typedef typename mozilla::detail::UnsignedIntegerTypeForEnum<TypedEnum>::Type
UnsignedIntegerType;
// Part 1:
// Test the bitwise binary operator i.e.
// result = t1 Op t2;
auto result = Op<o>(t1, t2);
// result = aT1 Op aT2;
auto result = Op<o>(aT1, aT2);
typedef decltype(result) ResultType;
RequireLiteralType<ResultType>();
TestNonConvertibilityForOneType<ResultType>();
UnsignedIntegerType unsignedIntegerResult
= Op<o>(UnsignedIntegerType(t1), UnsignedIntegerType(t2));
UnsignedIntegerType unsignedIntegerResult =
Op<o>(UnsignedIntegerType(aT1), UnsignedIntegerType(aT2));
MOZ_RELEASE_ASSERT(unsignedIntegerResult == UnsignedIntegerType(result));
MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerResult) == TypedEnum(result));
@ -282,11 +285,11 @@ void TestBinOp(const T1& t1, const T2& t2, const T3& t3)
// Part 2:
// Test the compound-assignment operator, i.e.
// result Op= t3;
// result Op= aT3;
TypedEnum newResult = result;
OpAssign<o>(newResult, t3);
OpAssign<o>(newResult, aT3);
UnsignedIntegerType unsignedIntegerNewResult = unsignedIntegerResult;
OpAssign<o>(unsignedIntegerNewResult, UnsignedIntegerType(t3));
OpAssign<o>(unsignedIntegerNewResult, UnsignedIntegerType(aT3));
MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerNewResult) == newResult);
// Part 3:
@ -307,19 +310,19 @@ void TestBinOp(const T1& t1, const T2& t2, const T3& t3)
// Similar to TestBinOp but testing the unary ~ operator.
template<typename TypedEnum, typename T>
void TestTilde(const T& t)
void TestTilde(const T& aT)
{
typedef typename mozilla::detail::UnsignedIntegerTypeForEnum<TypedEnum>::Type
UnsignedIntegerType;
auto result = ~t;
auto result = ~aT;
typedef decltype(result) ResultType;
RequireLiteralType<ResultType>();
TestNonConvertibilityForOneType<ResultType>();
UnsignedIntegerType unsignedIntegerResult = ~(UnsignedIntegerType(t));
UnsignedIntegerType unsignedIntegerResult = ~(UnsignedIntegerType(aT));
MOZ_RELEASE_ASSERT(unsignedIntegerResult == UnsignedIntegerType(result));
MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerResult) == TypedEnum(result));
@ -331,12 +334,12 @@ void TestTilde(const T& t)
// Helper dispatching a given triple of operands to all operator-specific
// testing functions.
template<typename TypedEnum, typename T1, typename T2, typename T3>
void TestAllOpsForGivenOperands(const T1& t1, const T2& t2, const T3& t3)
void TestAllOpsForGivenOperands(const T1& aT1, const T2& aT2, const T3& aT3)
{
TestBinOp<TypedEnum, '|'>(t1, t2, t3);
TestBinOp<TypedEnum, '&'>(t1, t2, t3);
TestBinOp<TypedEnum, '^'>(t1, t2, t3);
TestTilde<TypedEnum>(t1);
TestBinOp<TypedEnum, '|'>(aT1, aT2, aT3);
TestBinOp<TypedEnum, '&'>(aT1, aT2, aT3);
TestBinOp<TypedEnum, '^'>(aT1, aT2, aT3);
TestTilde<TypedEnum>(aT1);
}
// Helper building various triples of operands using a given operator,
@ -365,15 +368,15 @@ void TestAllOpsForOperandsBuiltUsingGivenOp()
auto bc_auto = Op<o>(b_auto, c_auto);
// On each row below, we pass a triple of operands. Keep in mind that this
// is going to be received as (t1, t2, t3) and the actual tests performed
// is going to be received as (aT1, aT2, aT3) and the actual tests performed
// will be of the form
//
// result = t1 Op t2;
// result Op= t3;
// result = aT1 Op aT2;
// result Op= aT3;
//
// For this reason, we carefully ensure that the values of (t1, t2)
// For this reason, we carefully ensure that the values of (aT1, aT2)
// systematically cover all types of such pairs; to limit complexity,
// we are not so careful with t3, and we just try to pass t3's
// we are not so careful with aT3, and we just try to pass aT3's
// that may lead to nontrivial bitwise operations.
TestAllOpsForGivenOperands<TypedEnum>(a_plain, b_plain, c_plain);
TestAllOpsForGivenOperands<TypedEnum>(a_plain, bc_plain, b_auto);
@ -408,15 +411,15 @@ TestTypedEnumBitField()
TestAllOpsForOperandsBuiltUsingGivenOp<TypedEnum, '^'>();
}
// Checks that enum bitwise expressions have the same non-convertibility properties as
// c++11 enum classes do, i.e. not implicitly convertible to anything
// (though *explicitly* convertible).
// Checks that enum bitwise expressions have the same non-convertibility
// properties as c++11 enum classes do, i.e. not implicitly convertible to
// anything (though *explicitly* convertible).
void TestNoConversionsBetweenUnrelatedTypes()
{
using mozilla::IsConvertible;
// Two typed enum classes having the same underlying integer type, to ensure that
// we would catch bugs accidentally allowing conversions in that case.
// Two typed enum classes having the same underlying integer type, to ensure
// that we would catch bugs accidentally allowing conversions in that case.
typedef CharEnumBitField T1;
typedef Nested::CharEnumBitField T2;
@ -434,9 +437,9 @@ void TestNoConversionsBetweenUnrelatedTypes()
static_assert(!IsConvertible<decltype(T1::A), decltype(T2::A | T2::B)>::value,
"should not be convertible");
// The following are #ifdef MOZ_HAVE_EXPLICIT_CONVERSION because
// without support for explicit conversion operators, we can't easily have these
// bad conversions completely removed. They still do fail to compile in practice,
// The following are #ifdef MOZ_HAVE_EXPLICIT_CONVERSION because without
// support for explicit conversion operators, we can't easily have these bad
// conversions completely removed. They still do fail to compile in practice,
// but not in a way that we can static_assert on.
#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
static_assert(!IsConvertible<decltype(T1::A | T1::B), T2>::value,

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -25,53 +26,46 @@ using mozilla::Vector;
do { \
bool cond = (c); \
MOZ_ASSERT(cond, "Failed assertion: " #c); \
if (!cond) \
if (!cond) { \
return false; \
} \
} while (false)
typedef UniquePtr<int> NewInt;
static_assert(sizeof(NewInt) == sizeof(int*),
"stored most efficiently");
static_assert(sizeof(NewInt) == sizeof(int*), "stored most efficiently");
static size_t ADestructorCalls = 0;
struct A
{
public:
A() : x(0) {}
virtual ~A() {
ADestructorCalls++;
}
public:
A() : mX(0) {}
virtual ~A() { ADestructorCalls++; }
int x;
int mX;
};
static size_t BDestructorCalls = 0;
struct B : public A
{
public:
B() : y(1) {}
~B() {
BDestructorCalls++;
}
public:
B() : mY(1) {}
~B() { BDestructorCalls++; }
int y;
int mY;
};
typedef UniquePtr<A> UniqueA;
typedef UniquePtr<B, UniqueA::DeleterType> UniqueB; // permit interconversion
static_assert(sizeof(UniqueA) == sizeof(A*),
"stored most efficiently");
static_assert(sizeof(UniqueB) == sizeof(B*),
"stored most efficiently");
static_assert(sizeof(UniqueA) == sizeof(A*), "stored most efficiently");
static_assert(sizeof(UniqueB) == sizeof(B*), "stored most efficiently");
struct DeleterSubclass : UniqueA::DeleterType {};
typedef UniquePtr<B, DeleterSubclass> UniqueC;
static_assert(sizeof(UniqueC) == sizeof(B*),
"stored most efficiently");
static_assert(sizeof(UniqueC) == sizeof(B*), "stored most efficiently");
static UniqueA
ReturnUniqueA()
@ -138,14 +132,14 @@ TestDefaultFreeGuts()
CHECK(a1 == nullptr);
a1.reset(new A);
CHECK(ADestructorCalls == 0);
CHECK(a1->x == 0);
CHECK(a1->mX == 0);
B* bp1 = new B;
bp1->x = 5;
bp1->mX = 5;
CHECK(BDestructorCalls == 0);
a1.reset(bp1);
CHECK(ADestructorCalls == 1);
CHECK(a1->x == 5);
CHECK(a1->mX == 5);
a1.reset(nullptr);
CHECK(ADestructorCalls == 2);
CHECK(BDestructorCalls == 1);
@ -163,11 +157,11 @@ TestDefaultFreeGuts()
CHECK(BDestructorCalls == 2);
B* bp3 = new B;
bp3->x = 42;
bp3->mX = 42;
UniqueB b2(bp3);
UniqueA a4(Move(b2));
CHECK(b2.get() == nullptr);
CHECK((*a4).x == 42);
CHECK((*a4).mX == 42);
CHECK(ADestructorCalls == 3);
CHECK(BDestructorCalls == 2);
@ -223,13 +217,14 @@ static size_t FreeClassCounter = 0;
struct FreeClass
{
public:
FreeClass() {}
public:
FreeClass() {}
void operator()(int* ptr) {
FreeClassCounter++;
delete ptr;
}
void operator()(int* aPtr)
{
FreeClassCounter++;
delete aPtr;
}
};
typedef UniquePtr<int, FreeClass> NewIntCustom;
@ -358,25 +353,26 @@ typedef void (&FreeSignature)(void*);
static size_t DeleteIntFunctionCallCount = 0;
static void
DeleteIntFunction(void* ptr)
DeleteIntFunction(void* aPtr)
{
DeleteIntFunctionCallCount++;
delete static_cast<int*>(ptr);
delete static_cast<int*>(aPtr);
}
static void
SetMallocedInt(UniquePtr<int, FreeSignature>& ptr, int i)
SetMallocedInt(UniquePtr<int, FreeSignature>& aPtr, int aI)
{
int* newPtr = static_cast<int*>(malloc(sizeof(int)));
*newPtr = i;
ptr.reset(newPtr);
*newPtr = aI;
aPtr.reset(newPtr);
}
static UniquePtr<int, FreeSignature>
MallocedInt(int i)
MallocedInt(int aI)
{
UniquePtr<int, FreeSignature> ptr(static_cast<int*>(malloc(sizeof(int))), free);
*ptr = i;
UniquePtr<int, FreeSignature>
ptr(static_cast<int*>(malloc(sizeof(int))), free);
*ptr = aI;
return Move(ptr);
}
static bool
@ -546,16 +542,15 @@ TestArray()
struct Q
{
Q() {}
Q(const Q& q) {}
Q() {}
Q(const Q&) {}
Q(Q& q, char c) {}
Q(Q&, char) {}
template<typename T>
Q(Q q, T&& t, int i)
{}
template<typename T>
Q(Q, T&&, int) {}
Q(int i, long j, double k, void* l) {}
Q(int, long, double, void*) {}
};
static int randomInt() { return 4; }
@ -589,20 +584,28 @@ TestMakeUnique()
int
main()
{
if (!TestDefaultFree())
if (!TestDefaultFree()) {
return 1;
if (!TestFreeClass())
}
if (!TestFreeClass()) {
return 1;
if (!TestReferenceDeleter())
}
if (!TestReferenceDeleter()) {
return 1;
}
#if SHOULD_TEST_FUNCTION_REFERENCE_DELETER
if (!TestFunctionReferenceDeleter())
if (!TestFunctionReferenceDeleter()) {
return 1;
}
#endif
if (!TestVector())
if (!TestVector()) {
return 1;
if (!TestArray())
}
if (!TestArray()) {
return 1;
if (!TestMakeUnique())
}
if (!TestMakeUnique()) {
return 1;
}
return 0;
}

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -10,17 +12,16 @@ using mozilla::WeakPtr;
// To have a class C support weak pointers, inherit from SupportsWeakPtr<C>.
class C : public SupportsWeakPtr<C>
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
int num;
void act() {}
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
int mNum;
void act() {}
};
static void
Example()
{
C* ptr = new C();
C* ptr = new C();
// Get weak pointers to ptr. The first time asWeakPtr is called
// a reference counted WeakReference object is created that
@ -31,7 +32,7 @@ Example()
// Test a weak pointer for validity before using it.
if (weak) {
weak->num = 17;
weak->mNum = 17;
weak->act();
}
@ -44,28 +45,26 @@ Example()
struct A : public SupportsWeakPtr<A>
{
MOZ_DECLARE_REFCOUNTED_TYPENAME(A)
int data;
MOZ_DECLARE_REFCOUNTED_TYPENAME(A)
int mData;
};
int
main()
{
A* a = new A;
// a2 is unused to test the case when we haven't initialized
// the internal WeakReference pointer.
A* a2 = new A;
a->data = 5;
a->mData = 5;
WeakPtr<A> ptr = a->asWeakPtr();
{
WeakPtr<A> ptr2 = a->asWeakPtr();
MOZ_RELEASE_ASSERT(ptr->data == 5);
WeakPtr<A> ptr3 = a->asWeakPtr();
MOZ_RELEASE_ASSERT(ptr->data == 5);
WeakPtr<A> ptr2 = a->asWeakPtr();
MOZ_RELEASE_ASSERT(ptr->mData == 5);
WeakPtr<A> ptr3 = a->asWeakPtr();
MOZ_RELEASE_ASSERT(ptr->mData == 5);
}
delete a;