mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 891177 - Remove Vector.h's js/TemplateLib.h dependency by introducing mfbt/TemplateLib.h with the necessary bits. r=terrence
--HG-- extra : rebase_source : e84231171d6bd6c1e2de8201b8c9563375723d01
This commit is contained in:
parent
4196fa2e0f
commit
5e2dbd029b
@ -15,10 +15,10 @@
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/ReentrancyGuard.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
namespace js {
|
||||
@ -540,7 +540,7 @@ struct DefaultHasher
|
||||
// Specialize hashing policy for pointer types. It assumes that the type is
|
||||
// at least word-aligned. For types with smaller size use PointerHasher.
|
||||
template <class T>
|
||||
struct DefaultHasher<T *> : PointerHasher<T *, tl::FloorLog2<sizeof(void *)>::result>
|
||||
struct DefaultHasher<T *> : PointerHasher<T *, mozilla::tl::FloorLog2<sizeof(void *)>::value>
|
||||
{};
|
||||
|
||||
// For doubles, we can xor the two uint32s.
|
||||
@ -890,7 +890,7 @@ class HashTable : private AllocPolicy
|
||||
static const unsigned sMinCapacity = 1 << sMinCapacityLog2;
|
||||
static const unsigned sMaxInit = JS_BIT(23);
|
||||
static const unsigned sMaxCapacity = JS_BIT(24);
|
||||
static const unsigned sHashBits = tl::BitSize<HashNumber>::result;
|
||||
static const unsigned sHashBits = mozilla::tl::BitSize<HashNumber>::value;
|
||||
static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25)
|
||||
static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75)
|
||||
static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1)
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "js/Utility.h"
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
#include "jspubtd.h"
|
||||
|
||||
|
@ -1,112 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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/. */
|
||||
|
||||
#ifndef js_TemplateLib_h
|
||||
#define js_TemplateLib_h
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
/*
|
||||
* Library of reusable template meta-functions (that is, functions on types and
|
||||
* compile-time values). Meta-functions are placed inside the 'tl' namespace to
|
||||
* avoid conflict with non-meta functions that logically have the same name
|
||||
* (e.g., js::tl::Min vs. js::Min).
|
||||
*/
|
||||
|
||||
namespace js {
|
||||
namespace tl {
|
||||
|
||||
/* Compute min/max/clamp. */
|
||||
template <size_t i, size_t j> struct Min {
|
||||
static const size_t result = i < j ? i : j;
|
||||
};
|
||||
template <size_t i, size_t j> struct Max {
|
||||
static const size_t result = i > j ? i : j;
|
||||
};
|
||||
template <size_t i, size_t min, size_t max> struct Clamp {
|
||||
static const size_t result = i < min ? min : (i > max ? max : i);
|
||||
};
|
||||
|
||||
/* Compute x^y. */
|
||||
template <size_t x, size_t y> struct Pow {
|
||||
static const size_t result = x * Pow<x, y - 1>::result;
|
||||
};
|
||||
template <size_t x> struct Pow<x,0> {
|
||||
static const size_t result = 1;
|
||||
};
|
||||
|
||||
/* Compute floor(log2(i)). */
|
||||
template <size_t i> struct FloorLog2 {
|
||||
static const size_t result = 1 + FloorLog2<i / 2>::result;
|
||||
};
|
||||
template <> struct FloorLog2<0> { /* Error */ };
|
||||
template <> struct FloorLog2<1> { static const size_t result = 0; };
|
||||
|
||||
/* Compute ceiling(log2(i)). */
|
||||
template <size_t i> struct CeilingLog2 {
|
||||
static const size_t result = FloorLog2<2 * i - 1>::result;
|
||||
};
|
||||
|
||||
/* Round up to the nearest power of 2. */
|
||||
template <size_t i> struct RoundUpPow2 {
|
||||
static const size_t result = size_t(1) << CeilingLog2<i>::result;
|
||||
};
|
||||
template <> struct RoundUpPow2<0> {
|
||||
static const size_t result = 1;
|
||||
};
|
||||
|
||||
/* Compute the number of bits in the given unsigned type. */
|
||||
template <class T> struct BitSize {
|
||||
static const size_t result = sizeof(T) * JS_BITS_PER_BYTE;
|
||||
};
|
||||
|
||||
/*
|
||||
* Produce an N-bit mask, where N <= BitSize<size_t>::result. Handle the
|
||||
* language-undefined edge case when N = BitSize<size_t>::result.
|
||||
*/
|
||||
template <size_t N> struct NBitMask {
|
||||
// Assert the precondition. On success this evaluates to 0. Otherwise it
|
||||
// triggers divide-by-zero at compile time: a guaranteed compile error in
|
||||
// C++11, and usually one in C++98. Add this value to |result| to assure
|
||||
// its computation.
|
||||
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::result);
|
||||
static const size_t result = (size_t(1) << N) - 1 + checkPrecondition;
|
||||
};
|
||||
template <> struct NBitMask<BitSize<size_t>::result> {
|
||||
static const size_t result = size_t(-1);
|
||||
};
|
||||
|
||||
/*
|
||||
* For the unsigned integral type size_t, compute a mask M for N such that
|
||||
* for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
|
||||
*/
|
||||
template <size_t N> struct MulOverflowMask {
|
||||
static const size_t result =
|
||||
~NBitMask<BitSize<size_t>::result - CeilingLog2<N>::result>::result;
|
||||
};
|
||||
template <> struct MulOverflowMask<0> { /* Error */ };
|
||||
template <> struct MulOverflowMask<1> { static const size_t result = 0; };
|
||||
|
||||
/*
|
||||
* Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized
|
||||
* array of T's is big enough to cause a ptrdiff_t overflow when subtracting
|
||||
* a pointer to the end of the array from the beginning.
|
||||
*/
|
||||
template <class T> struct UnsafeRangeSizeMask {
|
||||
/*
|
||||
* The '2' factor means the top bit is clear, sizeof(T) converts from
|
||||
* units of elements to bytes.
|
||||
*/
|
||||
static const size_t result = MulOverflowMask<2 * sizeof(T)>::result;
|
||||
};
|
||||
|
||||
template <bool cond, typename T, T v1, T v2> struct If { static const T result = v1; };
|
||||
template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T result = v2; };
|
||||
|
||||
} /* namespace tl */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* js_TemplateLib_h */
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/Compiler.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -23,8 +24,6 @@
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
/* The public JS engine namespace. */
|
||||
namespace JS {}
|
||||
|
||||
@ -354,7 +353,7 @@ template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_malloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return NULL;
|
||||
return (T *)js_malloc(numElems * sizeof(T));
|
||||
}
|
||||
@ -363,7 +362,7 @@ template <class T>
|
||||
static JS_ALWAYS_INLINE T *
|
||||
js_pod_calloc(size_t numElems)
|
||||
{
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return NULL;
|
||||
return (T *)js_calloc(numElems * sizeof(T));
|
||||
}
|
||||
|
@ -13,9 +13,9 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/ReentrancyGuard.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */
|
||||
#ifdef _MSC_VER
|
||||
@ -227,19 +227,19 @@ class Vector : private AllocPolicy
|
||||
*/
|
||||
template <int M, int Dummy>
|
||||
struct ElemSize {
|
||||
static const size_t result = sizeof(T);
|
||||
static const size_t value = sizeof(T);
|
||||
};
|
||||
template <int Dummy>
|
||||
struct ElemSize<0, Dummy> {
|
||||
static const size_t result = 1;
|
||||
static const size_t value = 1;
|
||||
};
|
||||
|
||||
static const size_t sInlineCapacity =
|
||||
tl::Min<N, sMaxInlineBytes / ElemSize<N, 0>::result>::result;
|
||||
mozilla::tl::Min<N, sMaxInlineBytes / ElemSize<N, 0>::value>::value;
|
||||
|
||||
/* Calculate inline buffer size; avoid 0-sized array. */
|
||||
static const size_t sInlineBytes =
|
||||
tl::Max<1, sInlineCapacity * ElemSize<N, 0>::result>::result;
|
||||
mozilla::tl::Max<1, sInlineCapacity * ElemSize<N, 0>::value>::value;
|
||||
|
||||
/* member data */
|
||||
|
||||
@ -648,7 +648,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
|
||||
if (incr == 1) {
|
||||
if (usingInlineStorage()) {
|
||||
/* This case occurs in ~70--80% of the calls to this function. */
|
||||
size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result;
|
||||
size_t newSize = mozilla::tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value;
|
||||
newCap = newSize / sizeof(T);
|
||||
goto convert;
|
||||
}
|
||||
@ -667,7 +667,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
|
||||
* It also ensures that the ((char *)end() - (char *)begin()) does not
|
||||
* overflow ptrdiff_t (see Bug 510319).
|
||||
*/
|
||||
if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) {
|
||||
if (mLength & mozilla::tl::MulOverflowMask<4 * sizeof(T)>::value) {
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
}
|
||||
@ -687,7 +687,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
|
||||
|
||||
/* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */
|
||||
if (newMinCap < mLength ||
|
||||
newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result)
|
||||
newMinCap & mozilla::tl::MulOverflowMask<2 * sizeof(T)>::value)
|
||||
{
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
|
@ -7,9 +7,9 @@
|
||||
#ifndef ds_BitArray_h
|
||||
#define ds_BitArray_h
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -54,7 +54,7 @@ class BitArray {
|
||||
private:
|
||||
inline void getMarkWordAndMask(size_t offset,
|
||||
uintptr_t *indexp, uintptr_t *maskp) const {
|
||||
*indexp = offset >> tl::FloorLog2<JS_BITS_PER_WORD>::result;
|
||||
*indexp = offset >> mozilla::tl::FloorLog2<JS_BITS_PER_WORD>::value;
|
||||
*maskp = uintptr_t(1) << (offset & (JS_BITS_PER_WORD - 1));
|
||||
}
|
||||
};
|
||||
|
@ -11,6 +11,7 @@
|
||||
using namespace js;
|
||||
|
||||
using mozilla::RoundUpPow2;
|
||||
using mozilla::tl::BitSize;
|
||||
|
||||
namespace js {
|
||||
namespace detail {
|
||||
@ -91,7 +92,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
|
||||
|
||||
// Guard for overflow.
|
||||
if (allocSizeWithHeader < n ||
|
||||
(allocSizeWithHeader & (size_t(1) << (tl::BitSize<size_t>::result - 1)))) {
|
||||
(allocSizeWithHeader & (size_t(1) << (BitSize<size_t>::value - 1)))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/MemoryChecking.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
// This data structure supports stacky LIFO allocation (mark/release and
|
||||
@ -31,8 +32,8 @@ JS_ALWAYS_INLINE
|
||||
char *
|
||||
AlignPtr(void *orig)
|
||||
{
|
||||
MOZ_STATIC_ASSERT(tl::FloorLog2<LIFO_ALLOC_ALIGN>::result ==
|
||||
tl::CeilingLog2<LIFO_ALLOC_ALIGN>::result,
|
||||
MOZ_STATIC_ASSERT(mozilla::tl::FloorLog2<LIFO_ALLOC_ALIGN>::value ==
|
||||
mozilla::tl::CeilingLog2<LIFO_ALLOC_ALIGN>::value,
|
||||
"LIFO_ALLOC_ALIGN must be a power of two");
|
||||
|
||||
char *result = (char *) ((uintptr_t(orig) + (LIFO_ALLOC_ALIGN - 1)) & (~LIFO_ALLOC_ALIGN + 1));
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/Nursery.h"
|
||||
#include "js/TemplateLib.h"
|
||||
#include "ion/IonCode.h"
|
||||
|
||||
extern "C" {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/MemoryMetrics.h"
|
||||
#include "js/PropertyKey.h"
|
||||
#include "js/TemplateLib.h"
|
||||
#include "js/Utility.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/Vector.h"
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "jslock.h"
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TemplateLib.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/ForkJoin.h"
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
@ -2070,7 +2071,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
* whether they have dynamically allocated slots and instead just copy
|
||||
* them over wholesale.
|
||||
*/
|
||||
char tmp[tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::result];
|
||||
char tmp[mozilla::tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::value];
|
||||
JS_ASSERT(size <= sizeof(tmp));
|
||||
|
||||
js_memcpy(tmp, a, size);
|
||||
|
@ -73,7 +73,6 @@ EXPORTS.js += [
|
||||
'../public/PropertyKey.h',
|
||||
'../public/RequiredDefines.h',
|
||||
'../public/RootingAPI.h',
|
||||
'../public/TemplateLib.h',
|
||||
'../public/Utility.h',
|
||||
'../public/Value.h',
|
||||
'../public/Vector.h',
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "js/TemplateLib.h"
|
||||
#include "vm/ObjectImpl.h"
|
||||
|
||||
#include "gc/Barrier-inl.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "js/TemplateLib.h"
|
||||
#include "vm/MatchPairs.h"
|
||||
#include "vm/Runtime.h"
|
||||
#include "yarr/MatchResult.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
@ -612,7 +613,7 @@ struct MallocProvider
|
||||
|
||||
template <class T>
|
||||
T *pod_malloc(size_t numElems) {
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result) {
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
Client *client = static_cast<Client *>(this);
|
||||
client->reportAllocationOverflow();
|
||||
return NULL;
|
||||
@ -622,7 +623,7 @@ struct MallocProvider
|
||||
|
||||
template <class T>
|
||||
T *pod_calloc(size_t numElems, JSCompartment *comp = NULL, JSContext *cx = NULL) {
|
||||
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result) {
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
Client *client = static_cast<Client *>(this);
|
||||
client->reportAllocationOverflow();
|
||||
return NULL;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
#include "jspropertytree.h"
|
||||
#include "jstypes.h"
|
||||
@ -108,7 +109,7 @@ static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2;
|
||||
* minimize footprint.
|
||||
*/
|
||||
struct ShapeTable {
|
||||
static const uint32_t HASH_BITS = tl::BitSize<HashNumber>::result;
|
||||
static const uint32_t HASH_BITS = mozilla::tl::BitSize<HashNumber>::value;
|
||||
static const uint32_t MIN_ENTRIES = 7;
|
||||
static const uint32_t MIN_SIZE_LOG2 = 4;
|
||||
static const uint32_t MIN_SIZE = JS_BIT(MIN_SIZE_LOG2);
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "assembler/wtf/Platform.h"
|
||||
#include "assembler/jit/ExecutableAllocator.h"
|
||||
#include "yarr/CheckedArithmetic.h"
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
namespace JSC { namespace Yarr {
|
||||
|
||||
|
111
mfbt/TemplateLib.h
Normal file
111
mfbt/TemplateLib.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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/. */
|
||||
|
||||
/*
|
||||
* Reusable template meta-functions on types and compile-time values. Meta-
|
||||
* functions are placed inside the 'tl' namespace to avoid conflict with non-
|
||||
* meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs.
|
||||
* mozilla::FloorLog2).
|
||||
*
|
||||
* When constexpr support becomes universal, we should probably use that instead
|
||||
* of some of these templates, for simplicity.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_TemplateLib_h
|
||||
#define mozilla_TemplateLib_h
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace tl {
|
||||
|
||||
/** Compute min/max. */
|
||||
template<size_t I, size_t J>
|
||||
struct Min
|
||||
{
|
||||
static const size_t value = I < J ? I : J;
|
||||
};
|
||||
template<size_t I, size_t J>
|
||||
struct Max
|
||||
{
|
||||
static const size_t value = I > J ? I : J;
|
||||
};
|
||||
|
||||
/** Compute floor(log2(i)). */
|
||||
template<size_t I>
|
||||
struct FloorLog2
|
||||
{
|
||||
static const size_t value = 1 + FloorLog2<I / 2>::value;
|
||||
};
|
||||
template<> struct FloorLog2<0> { /* Error */ };
|
||||
template<> struct FloorLog2<1> { static const size_t value = 0; };
|
||||
|
||||
/** Compute ceiling(log2(i)). */
|
||||
template<size_t I>
|
||||
struct CeilingLog2
|
||||
{
|
||||
static const size_t value = FloorLog2<2 * I - 1>::value;
|
||||
};
|
||||
|
||||
/** Round up to the nearest power of 2. */
|
||||
template<size_t I>
|
||||
struct RoundUpPow2
|
||||
{
|
||||
static const size_t value = size_t(1) << CeilingLog2<I>::value;
|
||||
};
|
||||
template<>
|
||||
struct RoundUpPow2<0>
|
||||
{
|
||||
static const size_t value = 1;
|
||||
};
|
||||
|
||||
/** Compute the number of bits in the given unsigned type. */
|
||||
template<typename T>
|
||||
struct BitSize
|
||||
{
|
||||
static const size_t value = sizeof(T) * CHAR_BIT;
|
||||
};
|
||||
|
||||
/**
|
||||
* Produce an N-bit mask, where N <= BitSize<size_t>::value. Handle the
|
||||
* language-undefined edge case when N = BitSize<size_t>::value.
|
||||
*/
|
||||
template<size_t N>
|
||||
struct NBitMask
|
||||
{
|
||||
// Assert the precondition. On success this evaluates to 0. Otherwise it
|
||||
// triggers divide-by-zero at compile time: a guaranteed compile error in
|
||||
// C++11, and usually one in C++98. Add this value to |value| to assure
|
||||
// its computation.
|
||||
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::value);
|
||||
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
|
||||
};
|
||||
template<>
|
||||
struct NBitMask<BitSize<size_t>::value>
|
||||
{
|
||||
static const size_t value = size_t(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
* For the unsigned integral type size_t, compute a mask M for N such that
|
||||
* for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
|
||||
*/
|
||||
template<size_t N>
|
||||
struct MulOverflowMask
|
||||
{
|
||||
static const size_t value =
|
||||
~NBitMask<BitSize<size_t>::value - CeilingLog2<N>::value>::value;
|
||||
};
|
||||
template<> struct MulOverflowMask<0> { /* Error */ };
|
||||
template<> struct MulOverflowMask<1> { static const size_t value = 0; };
|
||||
|
||||
} // namespace tl
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_TemplateLib_h */
|
@ -45,6 +45,7 @@ EXPORTS_mozilla += \
|
||||
SHA1.h \
|
||||
SplayTree.h \
|
||||
StandardInteger.h \
|
||||
TemplateLib.h \
|
||||
ThreadLocal.h \
|
||||
TypedEnum.h \
|
||||
Types.h \
|
||||
|
Loading…
Reference in New Issue
Block a user