mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1041914 - Convert the fourth quarter of MFBT to Gecko style. r=Ms2ger.
--HG-- extra : rebase_source : 588fa9c0d1e819e1826835c4ef4a1428a927bf93
This commit is contained in:
parent
b232975926
commit
6c3f5d7b8e
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
393
mfbt/STYLE
393
mfbt/STYLE
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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>();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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 "
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user