author | Jeff Walden <jwalden@mit.edu> |
Sun, 03 Jun 2012 20:36:43 -0700 | |
changeset 95872 | 1a0f4431003105008d31616e75b8db2d3291d54f |
parent 95871 | 4f44ffa3f9ff91a18d6bb493c9fec7b32045fbe7 |
child 95873 | 12b0df6ff60fafd95cb5c0c9d8358854ab894aa4 |
push id | 22859 |
push user | emorley@mozilla.com |
push date | Wed, 06 Jun 2012 08:23:59 +0000 |
treeherder | mozilla-central@a6c39a15557b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sparky |
milestone | 16.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/mfbt/Assertions.cpp +++ b/mfbt/Assertions.cpp @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Assertions.h" /* Implementations of runtime and static assertion macros for C and C++. */ extern "C" {
--- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of runtime and static assertion macros for C and C++. */ #ifndef mozilla_Assertions_h_ #define mozilla_Assertions_h_
--- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementations of various class and method modifier attributes. */ #ifndef mozilla_Attributes_h_ #define mozilla_Attributes_h_
--- a/mfbt/BloomFilter.h +++ b/mfbt/BloomFilter.h @@ -1,9 +1,9 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A counting Bloom filter implementation. This allows consumers to * do fast probabilistic "is item X in set Y?" testing which will * never answer "no" when the correct answer is "yes" (but might @@ -47,17 +47,18 @@ namespace mozilla { * 4*(N/M)**2 for this filter. In practice, if Y has a few hundred * elements then using a KeySize of 12 gives a reasonably low * incorrect answer rate. A KeySize of 12 has the additional benefit * of using exactly one page for the filter in typical hardware * configurations. */ template<unsigned KeySize, class T> -class BloomFilter { +class BloomFilter +{ /* * A counting Bloom filter with 8-bit counters. For now we assume * that having two hash functions is enough, but we may revisit that * decision later. * * The filter uses an array with 2**KeySize entries. * * Assuming a well-distributed hash function, a Bloom filter with @@ -96,17 +97,17 @@ class BloomFilter { * * What this means in practice is that for a few hundred keys using a * KeySize of 12 gives false positive rates on the order of 0.25-4%. * * Similarly, using a KeySize of 10 would lead to a 4% false * positive rate for N == 100 and to quite bad false positive * rates for larger N. */ -public: + public: BloomFilter() { MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big"); // Should we have a custom operator new using calloc instead and // require that we're allocated via the operator? clear(); } @@ -137,17 +138,17 @@ public: /* * Methods for add/remove/contain when we already have a hash computed */ void add(uint32_t hash); void remove(uint32_t hash); bool mightContain(uint32_t hash) const; -private: + private: static const size_t arraySize = (1 << KeySize); static const uint32_t keyMask = (1 << KeySize) - 1; static const uint32_t keyShift = 16; static uint32_t hash1(uint32_t hash) { return hash & keyMask; } static uint32_t hash2(uint32_t hash) { return (hash >> keyShift) & keyMask; } uint8_t& firstSlot(uint32_t hash) { return counters[hash1(hash)]; } @@ -159,74 +160,74 @@ private: uint8_t counters[arraySize]; }; template<unsigned KeySize, class T> inline void BloomFilter<KeySize, T>::clear() { - memset(counters, 0, arraySize); + memset(counters, 0, arraySize); } template<unsigned KeySize, class T> inline void BloomFilter<KeySize, T>::add(uint32_t hash) { - uint8_t& slot1 = firstSlot(hash); - if (MOZ_LIKELY(!full(slot1))) - ++slot1; + uint8_t& slot1 = firstSlot(hash); + if (MOZ_LIKELY(!full(slot1))) + ++slot1; - uint8_t& slot2 = secondSlot(hash); - if (MOZ_LIKELY(!full(slot2))) - ++slot2; + uint8_t& slot2 = secondSlot(hash); + if (MOZ_LIKELY(!full(slot2))) + ++slot2; } template<unsigned KeySize, class T> MOZ_ALWAYS_INLINE void BloomFilter<KeySize, T>::add(const T* t) { - uint32_t hash = t->hash(); - return add(hash); + uint32_t hash = t->hash(); + return add(hash); } template<unsigned KeySize, class T> inline void BloomFilter<KeySize, T>::remove(uint32_t hash) { - // If the slots are full, we don't know whether we bumped them to be - // there when we added or not, so just leave them full. - uint8_t& slot1 = firstSlot(hash); - if (MOZ_LIKELY(!full(slot1))) - --slot1; + // If the slots are full, we don't know whether we bumped them to be + // there when we added or not, so just leave them full. + uint8_t& slot1 = firstSlot(hash); + if (MOZ_LIKELY(!full(slot1))) + --slot1; - uint8_t& slot2 = secondSlot(hash); - if (MOZ_LIKELY(!full(slot2))) - --slot2; + uint8_t& slot2 = secondSlot(hash); + if (MOZ_LIKELY(!full(slot2))) + --slot2; } template<unsigned KeySize, class T> MOZ_ALWAYS_INLINE void BloomFilter<KeySize, T>::remove(const T* t) { - uint32_t hash = t->hash(); - remove(hash); + uint32_t hash = t->hash(); + remove(hash); } template<unsigned KeySize, class T> MOZ_ALWAYS_INLINE bool BloomFilter<KeySize, T>::mightContain(uint32_t hash) const { - // Check that all the slots for this hash contain something - return firstSlot(hash) && secondSlot(hash); + // Check that all the slots for this hash contain something + return firstSlot(hash) && secondSlot(hash); } template<unsigned KeySize, class T> MOZ_ALWAYS_INLINE bool BloomFilter<KeySize, T>::mightContain(const T* t) const { - uint32_t hash = t->hash(); - return mightContain(hash); + uint32_t hash = t->hash(); + return mightContain(hash); } } // namespace mozilla #endif /* mozilla_BloomFilter_h_ */
--- a/mfbt/GuardObjects.h +++ b/mfbt/GuardObjects.h @@ -1,10 +1,9 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sw=4 et tw=99 ft=cpp: */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implementation of macros to ensure correct use of RAII Auto* objects. */ #ifndef mozilla_GuardObjects_h #define mozilla_GuardObjects_h @@ -13,28 +12,29 @@ #include "mozilla/Types.h" #ifdef __cplusplus #ifdef DEBUG namespace mozilla { namespace detail { + /* * The following classes are designed to cause assertions to detect * inadvertent use of guard objects as temporaries. In other words, * when we have a guard object whose only purpose is its constructor and * destructor (and is never otherwise referenced), the intended use * might be: * - * AutoRestore savePainting(mIsPainting); + * AutoRestore savePainting(mIsPainting); * * but is is easy to accidentally write: * - * AutoRestore(mIsPainting); + * AutoRestore(mIsPainting); * * which compiles just fine, but runs the destructor well before the * intended time. * * They work by adding (#ifdef DEBUG) an additional parameter to the * guard object's constructor, with a default value, so that users of * the guard object's API do not need to do anything. The default value * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998), @@ -67,52 +67,51 @@ namespace detail { * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla */ class MOZ_EXPORT_API(GuardObjectNotifier) { private: bool* statementDone; public: - GuardObjectNotifier() : statementDone(NULL) {} + GuardObjectNotifier() : statementDone(NULL) { } ~GuardObjectNotifier() { - *statementDone = true; + *statementDone = true; } void setStatementDone(bool* statementIsDone) { - statementDone = statementIsDone; + statementDone = statementIsDone; } }; class MOZ_EXPORT_API(GuardObjectNotificationReceiver) { private: bool statementDone; public: - GuardObjectNotificationReceiver() : statementDone(false) {} + GuardObjectNotificationReceiver() : statementDone(false) { } ~GuardObjectNotificationReceiver() { - /* - * Assert that the guard object was not used as a temporary. - * (Note that this assert might also fire if init is not called - * because the guard object's implementation is not using the - * above macros correctly.) - */ - MOZ_ASSERT(statementDone); + /* + * Assert that the guard object was not used as a temporary. (Note that + * this assert might also fire if init is not called because the guard + * object's implementation is not using the above macros correctly.) + */ + MOZ_ASSERT(statementDone); } void init(const GuardObjectNotifier& constNotifier) { - /* - * constNotifier is passed as a const reference so that we can pass a - * temporary, but we really intend it as non-const. - */ - GuardObjectNotifier& notifier = const_cast<GuardObjectNotifier&>(constNotifier); - notifier.setStatementDone(&statementDone); + /* + * constNotifier is passed as a const reference so that we can pass a + * temporary, but we really intend it as non-const. + */ + GuardObjectNotifier& notifier = const_cast<GuardObjectNotifier&>(constNotifier); + notifier.setStatementDone(&statementDone); } }; } /* namespace detail */ } /* namespace mozilla */ #endif /* DEBUG */
--- a/mfbt/HashFunctions.cpp +++ b/mfbt/HashFunctions.cpp @@ -1,18 +1,17 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* Implementations of hash functions */ +/* Implementations of hash functions. */ #include "mozilla/HashFunctions.h" + #include <string.h> namespace mozilla { MFBT_API(uint32_t) HashBytes(const void* bytes, size_t length) { uint32_t hash = 0; @@ -24,16 +23,15 @@ HashBytes(const void* bytes, size_t leng /* Do an explicitly unaligned load of the data. */ size_t data; memcpy(&data, b + i, sizeof(size_t)); hash = AddToHash(hash, data, sizeof(data)); } /* Get the remaining bytes. */ - for (; i < length; i++) { + for (; i < length; i++) hash = AddToHash(hash, b[i]); - } return hash; } } /* namespace mozilla */
--- a/mfbt/HashFunctions.h +++ b/mfbt/HashFunctions.h @@ -1,16 +1,14 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* Utilities for hashing */ +/* Utilities for hashing. */ /* * This file exports functions for hashing data down to a 32-bit value, * including: * * - HashString Hash a char* or uint16_t/wchar_t* of known or unknown * length. * @@ -21,26 +19,28 @@ * pointers, and function pointers. * * - AddToHash Add one or more values to the given hash. This supports the * same list of types as HashGeneric. * * * You can chain these functions together to hash complex objects. For example: * - * class ComplexObject { - * char* str; - * uint32_t uint1, uint2; - * void (*callbackFn)(); + * class ComplexObject + * { + * char* str; + * uint32_t uint1, uint2; + * void (*callbackFn)(); * - * uint32_t Hash() { - * uint32_t hash = HashString(str); - * hash = AddToHash(hash, uint1, uint2); - * return AddToHash(hash, callbackFn); - * } + * public: + * uint32_t hash() { + * uint32_t hash = HashString(str); + * hash = AddToHash(hash, uint1, uint2); + * return AddToHash(hash, callbackFn); + * } * }; * * If you want to hash an nsAString or nsACString, use the HashString functions * in nsHashKey.h. */ #ifndef mozilla_HashFunctions_h_ #define mozilla_HashFunctions_h_
--- a/mfbt/Likely.h +++ b/mfbt/Likely.h @@ -1,21 +1,22 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a * boolean predicate should be branch-predicted. */ -#ifndef Likely_h_ -#define Likely_h_ +#ifndef mozilla_Likely_h_ +#define mozilla_Likely_h_ #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2)) # define MOZ_LIKELY(x) (__builtin_expect((x), 1)) # define MOZ_UNLIKELY(x) (__builtin_expect((x), 0)) #else # define MOZ_LIKELY(x) (x) # define MOZ_UNLIKELY(x) (x) #endif -#endif /* Likely_h_ */ +#endif /* mozilla_Likely_h_ */
--- a/mfbt/LinkedList.h +++ b/mfbt/LinkedList.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 tw=80 et cin: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* A type-safe doubly-linked list class. */ /* * The classes LinkedList<T> and LinkedListElement<T> together form a * convenient, type-safe doubly-linked list implementation. @@ -15,46 +13,40 @@ * LinkedListElement<T>. A given object may be in only one linked list at a * time. * * For example, you might use LinkedList in a simple observer list class as * follows. * * class Observer : public LinkedListElement<Observer> * { - * void observe(char* topic) { ... } + * public: + * void observe(char* topic) { ... } * }; * * class ObserverContainer * { - * private: - * LinkedList<Observer> list; - * - * public: + * private: + * LinkedList<Observer> list; * - * void addObserver(Observer* observer) - * { - * // Will assert if |observer| is part of another list. - * list.insertBack(observer); - * } + * public: + * void addObserver(Observer* observer) { + * // Will assert if |observer| is part of another list. + * list.insertBack(observer); + * } * - * void removeObserver(Observer* observer) - * { - * // Will assert if |observer| is not part of some list. - * observer.remove(); - * } + * void removeObserver(Observer* observer) { + * // Will assert if |observer| is not part of some list. + * observer.remove(); + * } * - * void notifyObservers(char* topic) - * { - * for (Observer* o = list.getFirst(); - * o != NULL; - * o = o->getNext()) { - * o->Observe(topic); + * void notifyObservers(char* topic) { + * for (Observer* o = list.getFirst(); o != NULL; o = o->getNext()) + * o->Observe(topic); * } - * } * }; * */ #ifndef mozilla_LinkedList_h_ #define mozilla_LinkedList_h_ #include "mozilla/Assertions.h" @@ -99,326 +91,295 @@ class LinkedListElement * pointer to its iterator in the object in order to accomplish this. Not * only would this waste space, but you'd have to remember to update that * pointer every time you added or removed the object from a list. * * In-place, constant-time removal is a killer feature of doubly-linked * lists, and supporting this painlessly was a key design criterion. */ -private: + private: LinkedListElement* next; LinkedListElement* prev; const bool isSentinel; -public: - LinkedListElement() - : next(this) - , prev(this) - , isSentinel(false) - { - } + public: + LinkedListElement() : next(this), prev(this), isSentinel(false) { } /* * Get the next element in the list, or NULL if this is the last element in * the list. */ - T* getNext() - { - return next->asT(); + T* getNext() { + return next->asT(); } - const T* getNext() const - { - return next->asT(); + const T* getNext() const { + return next->asT(); } /* * Get the previous element in the list, or NULL if this is the first element * in the list. */ - T* getPrevious() - { - return prev->asT(); + T* getPrevious() { + return prev->asT(); } - const T* getPrevious() const - { - return prev->asT(); + const T* getPrevious() const { + return prev->asT(); } /* * Insert elem after this element in the list. |this| must be part of a * linked list when you call setNext(); otherwise, this method will assert. */ - void setNext(T* elem) - { + void setNext(T* elem) { MOZ_ASSERT(isInList()); setNextUnsafe(elem); } /* * Insert elem before this element in the list. |this| must be part of a * linked list when you call setPrevious(); otherwise, this method will * assert. */ - void setPrevious(T* elem) - { - MOZ_ASSERT(isInList()); - setPreviousUnsafe(elem); + void setPrevious(T* elem) { + MOZ_ASSERT(isInList()); + setPreviousUnsafe(elem); } /* * Remove this element from the list which contains it. If this element is * not currently part of a linked list, this method asserts. */ - void remove() - { - MOZ_ASSERT(isInList()); + void remove() { + MOZ_ASSERT(isInList()); - prev->next = next; - next->prev = prev; - next = this; - prev = this; + prev->next = next; + next->prev = prev; + next = this; + prev = this; } /* * Return true if |this| part is of a linked list, and false otherwise. */ - bool isInList() const - { - MOZ_ASSERT((next == this) == (prev == this)); - return next != this; + bool isInList() const { + MOZ_ASSERT((next == this) == (prev == this)); + return next != this; } -private: - LinkedListElement& operator=(const LinkedList<T>& other) MOZ_DELETE; - LinkedListElement(const LinkedList<T>& other) MOZ_DELETE; - + private: friend class LinkedList<T>; enum NodeKind { - NODE_KIND_NORMAL, - NODE_KIND_SENTINEL + NODE_KIND_NORMAL, + NODE_KIND_SENTINEL }; LinkedListElement(NodeKind nodeKind) - : next(this) - , prev(this) - , isSentinel(nodeKind == NODE_KIND_SENTINEL) + : next(this), + prev(this), + isSentinel(nodeKind == NODE_KIND_SENTINEL) { } /* * Return |this| cast to T* if we're a normal node, or return NULL if we're * a sentinel node. */ - T* asT() - { - if (isSentinel) - return NULL; + T* asT() { + if (isSentinel) + return NULL; - return static_cast<T*>(this); + return static_cast<T*>(this); } - const T* asT() const - { - if (isSentinel) - return NULL; + const T* asT() const { + if (isSentinel) + return NULL; - return static_cast<const T*>(this); + return static_cast<const T*>(this); } /* * Insert elem after this element, but don't check that this element is in * the list. This is called by LinkedList::insertFront(). */ - void setNextUnsafe(T* elem) - { - LinkedListElement *listElem = static_cast<LinkedListElement*>(elem); - MOZ_ASSERT(!listElem->isInList()); + void setNextUnsafe(T* elem) { + LinkedListElement *listElem = static_cast<LinkedListElement*>(elem); + MOZ_ASSERT(!listElem->isInList()); - listElem->next = this->next; - listElem->prev = this; - this->next->prev = listElem; - this->next = listElem; + listElem->next = this->next; + listElem->prev = this; + this->next->prev = listElem; + this->next = listElem; } /* * Insert elem before this element, but don't check that this element is in * the list. This is called by LinkedList::insertBack(). */ - void setPreviousUnsafe(T* elem) - { - LinkedListElement<T>* listElem = static_cast<LinkedListElement<T>*>(elem); - MOZ_ASSERT(!listElem->isInList()); + void setPreviousUnsafe(T* elem) { + LinkedListElement<T>* listElem = static_cast<LinkedListElement<T>*>(elem); + MOZ_ASSERT(!listElem->isInList()); - listElem->next = this; - listElem->prev = this->prev; - this->prev->next = listElem; - this->prev = listElem; + listElem->next = this; + listElem->prev = this->prev; + this->prev->next = listElem; + this->prev = listElem; } + + private: + LinkedListElement& operator=(const LinkedList<T>& other) MOZ_DELETE; + LinkedListElement(const LinkedList<T>& other) MOZ_DELETE; }; template<typename T> class LinkedList { -private: + private: LinkedListElement<T> sentinel; -public: - LinkedList& operator=(const LinkedList<T>& other) MOZ_DELETE; - LinkedList(const LinkedList<T>& other) MOZ_DELETE; - - LinkedList() - : sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL) - { - } + public: + LinkedList() : sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL) { } /* * Add elem to the front of the list. */ - void insertFront(T* elem) - { - /* Bypass setNext()'s this->isInList() assertion. */ - sentinel.setNextUnsafe(elem); + void insertFront(T* elem) { + /* Bypass setNext()'s this->isInList() assertion. */ + sentinel.setNextUnsafe(elem); } /* * Add elem to the back of the list. */ - void insertBack(T* elem) - { - sentinel.setPreviousUnsafe(elem); + void insertBack(T* elem) { + sentinel.setPreviousUnsafe(elem); } /* * Get the first element of the list, or NULL if the list is empty. */ - T* getFirst() - { - return sentinel.getNext(); + T* getFirst() { + return sentinel.getNext(); } - const T* getFirst() const - { - return sentinel.getNext(); + const T* getFirst() const { + return sentinel.getNext(); } /* * Get the last element of the list, or NULL if the list is empty. */ - T* getLast() - { - return sentinel.getPrevious(); + T* getLast() { + return sentinel.getPrevious(); } - const T* getLast() const - { - return sentinel.getPrevious(); + const T* getLast() const { + return sentinel.getPrevious(); } /* * Get and remove the first element of the list. If the list is empty, * return NULL. */ - T* popFirst() - { - T* ret = sentinel.getNext(); - if (ret) - static_cast<LinkedListElement<T>*>(ret)->remove(); - - return ret; + T* popFirst() { + T* ret = sentinel.getNext(); + if (ret) + static_cast<LinkedListElement<T>*>(ret)->remove(); + return ret; } /* * Get and remove the last element of the list. If the list is empty, * return NULL. */ - T* popLast() - { - T* ret = sentinel.getPrevious(); - if (ret) - static_cast<LinkedListElement<T>*>(ret)->remove(); - - return ret; + T* popLast() { + T* ret = sentinel.getPrevious(); + if (ret) + static_cast<LinkedListElement<T>*>(ret)->remove(); + return ret; } /* * Return true if the list is empty, or false otherwise. */ - bool isEmpty() const - { - return !sentinel.isInList(); + bool isEmpty() const { + return !sentinel.isInList(); } /* * Remove all the elements from the list. * * This runs in time linear to the list's length, because we have to mark * each element as not in the list. */ - void clear() - { - while (popFirst()) - continue; + void clear() { + while (popFirst()) + continue; } /* * In a debug build, make sure that the list is sane (no cycles, consistent * next/prev pointers, only one sentinel). Has no effect in release builds. */ - void debugAssertIsSane() const - { + void debugAssertIsSane() const { #ifdef DEBUG - /* - * Check for cycles in the forward singly-linked list using the - * tortoise/hare algorithm. - */ - for (const LinkedListElement<T>* slow = sentinel.next, - * fast1 = sentinel.next->next, - * fast2 = sentinel.next->next->next; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; - slow = slow->next, - fast1 = fast2->next, - fast2 = fast1->next) { + const LinkedListElement<T>* slow; + const LinkedListElement<T>* fast1; + const LinkedListElement<T>* fast2; - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } + /* + * Check for cycles in the forward singly-linked list using the + * tortoise/hare algorithm. + */ + for (slow = sentinel.next, + fast1 = sentinel.next->next, + fast2 = sentinel.next->next->next; + slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow = slow->next, fast1 = fast2->next, fast2 = fast1->next) + { + MOZ_ASSERT(slow != fast1); + MOZ_ASSERT(slow != fast2); + } - /* Check for cycles in the backward singly-linked list. */ - for (const LinkedListElement<T>* slow = sentinel.prev, - * fast1 = sentinel.prev->prev, - * fast2 = sentinel.prev->prev->prev; - slow != sentinel && fast1 != sentinel && fast2 != sentinel; - slow = slow->prev, - fast1 = fast2->prev, - fast2 = fast1->prev) { - - MOZ_ASSERT(slow != fast1); - MOZ_ASSERT(slow != fast2); - } + /* Check for cycles in the backward singly-linked list. */ + for (slow = sentinel.prev, + fast1 = sentinel.prev->prev, + fast2 = sentinel.prev->prev->prev; + slow != sentinel && fast1 != sentinel && fast2 != sentinel; + slow = slow->prev, fast1 = fast2->prev, fast2 = fast1->prev) + { + MOZ_ASSERT(slow != fast1); + MOZ_ASSERT(slow != fast2); + } - /* - * Check that |sentinel| is the only node in the list with - * isSentinel == true. - */ - for (const LinkedListElement<T>* elem = sentinel.next; - elem != sentinel; - elem = elem->next) { - - MOZ_ASSERT(!elem->isSentinel); - } + /* + * Check that |sentinel| is the only node in the list with + * isSentinel == true. + */ + for (const LinkedListElement<T>* elem = sentinel.next; + elem != sentinel; + elem = elem->next) + { + MOZ_ASSERT(!elem->isSentinel); + } - /* Check that the next/prev pointers match up. */ - const LinkedListElement<T>* prev = sentinel; - const LinkedListElement<T>* cur = sentinel.next; - do { - MOZ_ASSERT(cur->prev == prev); - MOZ_ASSERT(prev->next == cur); + /* Check that the next/prev pointers match up. */ + const LinkedListElement<T>* prev = sentinel; + const LinkedListElement<T>* cur = sentinel.next; + do { + MOZ_ASSERT(cur->prev == prev); + MOZ_ASSERT(prev->next == cur); - prev = cur; - cur = cur->next; - } while (cur != sentinel); + prev = cur; + cur = cur->next; + } while (cur != sentinel); #endif /* ifdef DEBUG */ } + + private: + LinkedList& operator=(const LinkedList<T>& other) MOZ_DELETE; + LinkedList(const LinkedList<T>& other) MOZ_DELETE; }; } /* namespace mozilla */ #endif /* ifdef __cplusplus */ #endif /* ifdef mozilla_LinkedList_h_ */
--- a/mfbt/RangedPtr.h +++ b/mfbt/RangedPtr.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * Implements a smart pointer asserted to remain within a range specified at * construction. */ @@ -33,215 +31,215 @@ namespace mozilla { * passing pointers), if the method being called isn't inlined. If you are in * extremely performance-critical code, you may want to be careful using this * smart pointer as an argument type. * * RangedPtr<T> intentionally does not implicitly convert to T*. Use get() to * explicitly convert to T*. Keep in mind that the raw pointer of course won't * implement bounds checking in debug builds. */ -template <typename T> +template<typename T> class RangedPtr { T* ptr; #ifdef DEBUG T* const rangeStart; T* const rangeEnd; #endif void checkSanity() { - MOZ_ASSERT(rangeStart <= ptr); - MOZ_ASSERT(ptr <= rangeEnd); + MOZ_ASSERT(rangeStart <= ptr); + MOZ_ASSERT(ptr <= rangeEnd); } /* Creates a new pointer for |ptr|, restricted to this pointer's range. */ RangedPtr<T> create(T *ptr) const { #ifdef DEBUG - return RangedPtr<T>(ptr, rangeStart, rangeEnd); + return RangedPtr<T>(ptr, rangeStart, rangeEnd); #else - return RangedPtr<T>(ptr, NULL, size_t(0)); + return RangedPtr<T>(ptr, NULL, size_t(0)); #endif } public: RangedPtr(T* p, T* start, T* end) : ptr(p) #ifdef DEBUG , rangeStart(start), rangeEnd(end) #endif { - MOZ_ASSERT(rangeStart <= rangeEnd); - checkSanity(); + MOZ_ASSERT(rangeStart <= rangeEnd); + checkSanity(); } RangedPtr(T* p, T* start, size_t length) : ptr(p) #ifdef DEBUG , rangeStart(start), rangeEnd(start + length) #endif { - MOZ_ASSERT(length <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart)); - checkSanity(); + MOZ_ASSERT(length <= size_t(-1) / sizeof(T)); + MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart)); + checkSanity(); } /* Equivalent to RangedPtr(p, p, length). */ RangedPtr(T* p, size_t length) : ptr(p) #ifdef DEBUG , rangeStart(p), rangeEnd(p + length) #endif { - MOZ_ASSERT(length <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart)); - checkSanity(); + MOZ_ASSERT(length <= size_t(-1) / sizeof(T)); + MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart)); + checkSanity(); } /* Equivalent to RangedPtr(arr, arr, N). */ template<size_t N> RangedPtr(T arr[N]) : ptr(arr) #ifdef DEBUG , rangeStart(arr), rangeEnd(arr + N) #endif { checkSanity(); } T* get() const { - return ptr; + return ptr; } /* * You can only assign one RangedPtr into another if the two pointers have * the same valid range: * * char arr1[] = "hi"; * char arr2[] = "bye"; * RangedPtr<char> p1(arr1, 2); * p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works * p1 = RangedPtr<char>(arr2, 3); // asserts */ RangedPtr<T>& operator=(const RangedPtr<T>& other) { - MOZ_ASSERT(rangeStart == other.rangeStart); - MOZ_ASSERT(rangeEnd == other.rangeEnd); - ptr = other.ptr; - checkSanity(); - return *this; + MOZ_ASSERT(rangeStart == other.rangeStart); + MOZ_ASSERT(rangeEnd == other.rangeEnd); + ptr = other.ptr; + checkSanity(); + return *this; } RangedPtr<T> operator+(size_t inc) { - MOZ_ASSERT(inc <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(ptr + inc > ptr); - return create(ptr + inc); + MOZ_ASSERT(inc <= size_t(-1) / sizeof(T)); + MOZ_ASSERT(ptr + inc > ptr); + return create(ptr + inc); } RangedPtr<T> operator-(size_t dec) { - MOZ_ASSERT(dec <= size_t(-1) / sizeof(T)); - MOZ_ASSERT(ptr - dec < ptr); - return create(ptr - dec); + MOZ_ASSERT(dec <= size_t(-1) / sizeof(T)); + MOZ_ASSERT(ptr - dec < ptr); + return create(ptr - dec); } /* * You can assign a raw pointer into a RangedPtr if the raw pointer is * within the range specified at creation. */ template <typename U> RangedPtr<T>& operator=(U* p) { - *this = create(p); - return *this; + *this = create(p); + return *this; } template <typename U> RangedPtr<T>& operator=(const RangedPtr<U>& p) { - MOZ_ASSERT(rangeStart <= p.ptr); - MOZ_ASSERT(p.ptr <= rangeEnd); - ptr = p.ptr; - checkSanity(); - return *this; + MOZ_ASSERT(rangeStart <= p.ptr); + MOZ_ASSERT(p.ptr <= rangeEnd); + ptr = p.ptr; + checkSanity(); + return *this; } RangedPtr<T>& operator++() { - return (*this += 1); + return (*this += 1); } RangedPtr<T> operator++(int) { - RangedPtr<T> rcp = *this; - ++*this; - return rcp; + RangedPtr<T> rcp = *this; + ++*this; + return rcp; } RangedPtr<T>& operator--() { - return (*this -= 1); + return (*this -= 1); } RangedPtr<T> operator--(int) { - RangedPtr<T> rcp = *this; - --*this; - return rcp; + RangedPtr<T> rcp = *this; + --*this; + return rcp; } RangedPtr<T>& operator+=(size_t inc) { - this->operator=<T>(*this + inc); - return *this; + *this = *this + inc; + return *this; } RangedPtr<T>& operator-=(size_t dec) { - this->operator=<T>(*this - dec); - return *this; + *this = *this - dec; + return *this; } T& operator[](int index) const { - MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T)); - return *create(ptr + index); + MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T)); + return *create(ptr + index); } T& operator*() const { - return *ptr; + return *ptr; } template <typename U> bool operator==(const RangedPtr<U>& other) const { - return ptr == other.ptr; + return ptr == other.ptr; } template <typename U> bool operator!=(const RangedPtr<U>& other) const { - return !(*this == other); + return !(*this == other); } template<typename U> bool operator==(const U* u) const { - return ptr == u; + return ptr == u; } template<typename U> bool operator!=(const U* u) const { - return !(*this == u); + return !(*this == u); } template <typename U> bool operator<(const RangedPtr<U>& other) const { - return ptr < other.ptr; + return ptr < other.ptr; } template <typename U> bool operator<=(const RangedPtr<U>& other) const { - return ptr <= other.ptr; + return ptr <= other.ptr; } template <typename U> bool operator>(const RangedPtr<U>& other) const { - return ptr > other.ptr; + return ptr > other.ptr; } template <typename U> bool operator>=(const RangedPtr<U>& other) const { - return ptr >= other.ptr; + return ptr >= other.ptr; } size_t operator-(const RangedPtr<T>& other) const { - MOZ_ASSERT(ptr >= other.ptr); - return PointerRangeSize(other.ptr, ptr); + MOZ_ASSERT(ptr >= other.ptr); + return PointerRangeSize(other.ptr, ptr); } private: RangedPtr() MOZ_DELETE; T* operator&() MOZ_DELETE; operator T*() const MOZ_DELETE; };
--- a/mfbt/RefPtr.h +++ b/mfbt/RefPtr.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Helpers for defining and using refcounted objects. */ #ifndef mozilla_RefPtr_h_ #define mozilla_RefPtr_h_ @@ -42,46 +40,46 @@ template<typename T> OutParamRef<T> byRe * state distinguishes use-before-ref (refcount==0) from * use-after-destroy (refcount==-0xdead). */ template<typename T> class RefCounted { friend class RefPtr<T>; -public: + public: RefCounted() : refCnt(0) { } ~RefCounted() { MOZ_ASSERT(refCnt == -0xdead); } // Compatibility with nsRefPtr. void AddRef() { - MOZ_ASSERT(refCnt >= 0); - ++refCnt; + MOZ_ASSERT(refCnt >= 0); + ++refCnt; } void Release() { - MOZ_ASSERT(refCnt > 0); - if (0 == --refCnt) { + MOZ_ASSERT(refCnt > 0); + if (0 == --refCnt) { #ifdef DEBUG - refCnt = -0xdead; + refCnt = -0xdead; #endif - delete static_cast<T*>(this); - } + delete static_cast<T*>(this); + } } // Compatibility with wtf::RefPtr. void ref() { AddRef(); } void deref() { Release(); } int refCount() const { return refCnt; } bool hasOneRef() const { - MOZ_ASSERT(refCnt > 0); - return refCnt == 1; + MOZ_ASSERT(refCnt > 0); + return refCnt == 1; } -private: + private: int refCnt; }; /** * RefPtr points to a refcounted thing that has AddRef and Release * methods to increase/decrease the refcount, respectively. After a * RefPtr<T> is assigned a T*, the T* can be used through the RefPtr * as if it were a T*. @@ -92,119 +90,117 @@ private: */ template<typename T> class RefPtr { // To allow them to use unref() friend class TemporaryRef<T>; friend class OutParamRef<T>; - struct dontRef {}; + struct DontRef {}; -public: + public: RefPtr() : ptr(0) { } RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {} RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {} RefPtr(T* t) : ptr(ref(t)) {} template<typename U> RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {} ~RefPtr() { unref(ptr); } RefPtr& operator=(const RefPtr& o) { - assign(ref(o.ptr)); - return *this; + assign(ref(o.ptr)); + return *this; } RefPtr& operator=(const TemporaryRef<T>& o) { - assign(o.drop()); - return *this; + assign(o.drop()); + return *this; } RefPtr& operator=(T* t) { - assign(ref(t)); - return *this; + assign(ref(t)); + return *this; } template<typename U> RefPtr& operator=(const RefPtr<U>& o) { - assign(ref(o.get())); - return *this; + assign(ref(o.get())); + return *this; } TemporaryRef<T> forget() { - T* tmp = ptr; - ptr = 0; - return TemporaryRef<T>(tmp, dontRef()); + T* tmp = ptr; + ptr = 0; + return TemporaryRef<T>(tmp, DontRef()); } T* get() const { return ptr; } operator T*() const { return ptr; } T* operator->() const { return ptr; } T& operator*() const { return *ptr; } template<typename U> operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); } -private: + private: void assign(T* t) { - unref(ptr); - ptr = t; + unref(ptr); + ptr = t; } T* ptr; static MOZ_ALWAYS_INLINE T* ref(T* t) { - if (t) { - t->AddRef(); - } - return t; + if (t) + t->AddRef(); + return t; } static MOZ_ALWAYS_INLINE void unref(T* t) { - if (t) { - t->Release(); - } + if (t) + t->Release(); } }; /** * TemporaryRef<T> represents an object that holds a temporary * reference to a T. TemporaryRef objects can't be manually ref'd or * unref'd (being temporaries, not lvalues), so can only relinquish * references to other objects, or unref on destruction. */ template<typename T> class TemporaryRef { // To allow it to construct TemporaryRef from a bare T* friend class RefPtr<T>; - typedef typename RefPtr<T>::dontRef dontRef; + typedef typename RefPtr<T>::DontRef DontRef; -public: + public: TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {} TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {} template<typename U> TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {} ~TemporaryRef() { RefPtr<T>::unref(ptr); } T* drop() const { - T* tmp = ptr; - ptr = 0; - return tmp; + T* tmp = ptr; + ptr = 0; + return tmp; } -private: - TemporaryRef(T* t, const dontRef&) : ptr(t) {} + private: + TemporaryRef(T* t, const DontRef&) : ptr(t) {} mutable T* ptr; - TemporaryRef(); - TemporaryRef& operator=(const TemporaryRef&); + TemporaryRef() MOZ_DELETE; + void operator=(const TemporaryRef&) MOZ_DELETE; }; /** * OutParamRef is a wrapper that tracks a refcounted pointer passed as * an outparam argument to a function. OutParamRef implements COM T** * outparam semantics: this requires the callee to AddRef() the T* * returned through the T** outparam on behalf of the caller. This * means the caller (through OutParamRef) must Release() the old @@ -216,42 +212,42 @@ private: * outparams and passing OutParamRef<T> to T**. Prefer RefPtr<T>* * outparams over T** outparams. */ template<typename T> class OutParamRef { friend OutParamRef byRef<T>(RefPtr<T>&); -public: + public: ~OutParamRef() { - RefPtr<T>::unref(refPtr.ptr); - refPtr.ptr = tmp; + RefPtr<T>::unref(refPtr.ptr); + refPtr.ptr = tmp; } operator T**() { return &tmp; } -private: + private: OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {} RefPtr<T>& refPtr; T* tmp; OutParamRef() MOZ_DELETE; OutParamRef& operator=(const OutParamRef&) MOZ_DELETE; }; /** * byRef cooperates with OutParamRef to implement COM outparam semantics. */ template<typename T> OutParamRef<T> byRef(RefPtr<T>& ptr) { - return OutParamRef<T>(ptr); + return OutParamRef<T>(ptr); } } // namespace mozilla #endif // mozilla_RefPtr_h_ #if 0 @@ -259,152 +255,152 @@ byRef(RefPtr<T>& ptr) // Command line that builds these tests // // cp RefPtr.h test.cc && g++ -g -Wall -pedantic -DDEBUG -o test test.cc && ./test using namespace mozilla; struct Foo : public RefCounted<Foo> { - Foo() : dead(false) { } - ~Foo() { - MOZ_ASSERT(!dead); - dead = true; - numDestroyed++; - } + Foo() : dead(false) { } + ~Foo() { + MOZ_ASSERT(!dead); + dead = true; + numDestroyed++; + } - bool dead; - static int numDestroyed; + bool dead; + static int numDestroyed; }; int Foo::numDestroyed; struct Bar : public Foo { }; TemporaryRef<Foo> NewFoo() { - return RefPtr<Foo>(new Foo()); + return RefPtr<Foo>(new Foo()); } TemporaryRef<Foo> NewBar() { - return new Bar(); + return new Bar(); } void GetNewFoo(Foo** f) { - *f = new Bar(); - // Kids, don't try this at home - (*f)->AddRef(); + *f = new Bar(); + // Kids, don't try this at home + (*f)->AddRef(); } void GetPassedFoo(Foo** f) { - // Kids, don't try this at home - (*f)->AddRef(); + // Kids, don't try this at home + (*f)->AddRef(); } void GetNewFoo(RefPtr<Foo>* f) { - *f = new Bar(); + *f = new Bar(); } void GetPassedFoo(RefPtr<Foo>* f) {} TemporaryRef<Foo> GetNullFoo() { - return 0; + return 0; } int main(int argc, char** argv) { - // This should blow up + // This should blow up // Foo* f = new Foo(); delete f; - MOZ_ASSERT(0 == Foo::numDestroyed); - { - RefPtr<Foo> f = new Foo(); - MOZ_ASSERT(f->refCount() == 1); - } + MOZ_ASSERT(0 == Foo::numDestroyed); + { + RefPtr<Foo> f = new Foo(); + MOZ_ASSERT(f->refCount() == 1); + } + MOZ_ASSERT(1 == Foo::numDestroyed); + + { + RefPtr<Foo> f1 = NewFoo(); + RefPtr<Foo> f2(NewFoo()); MOZ_ASSERT(1 == Foo::numDestroyed); + } + MOZ_ASSERT(3 == Foo::numDestroyed); + { + RefPtr<Foo> b = NewBar(); + MOZ_ASSERT(3 == Foo::numDestroyed); + } + MOZ_ASSERT(4 == Foo::numDestroyed); + + { + RefPtr<Foo> f1; { - RefPtr<Foo> f1 = NewFoo(); - RefPtr<Foo> f2(NewFoo()); - MOZ_ASSERT(1 == Foo::numDestroyed); - } - MOZ_ASSERT(3 == Foo::numDestroyed); - - { - RefPtr<Foo> b = NewBar(); - MOZ_ASSERT(3 == Foo::numDestroyed); + f1 = new Foo(); + RefPtr<Foo> f2(f1); + RefPtr<Foo> f3 = f2; + MOZ_ASSERT(4 == Foo::numDestroyed); } MOZ_ASSERT(4 == Foo::numDestroyed); + } + MOZ_ASSERT(5 == Foo::numDestroyed); - { - RefPtr<Foo> f1; - { - f1 = new Foo(); - RefPtr<Foo> f2(f1); - RefPtr<Foo> f3 = f2; - MOZ_ASSERT(4 == Foo::numDestroyed); - } - MOZ_ASSERT(4 == Foo::numDestroyed); - } - MOZ_ASSERT(5 == Foo::numDestroyed); + { + RefPtr<Foo> f = new Foo(); + f.forget(); + MOZ_ASSERT(6 == Foo::numDestroyed); + } - { - RefPtr<Foo> f = new Foo(); - f.forget(); - MOZ_ASSERT(6 == Foo::numDestroyed); - } + { + RefPtr<Foo> f = new Foo(); + GetNewFoo(byRef(f)); + MOZ_ASSERT(7 == Foo::numDestroyed); + } + MOZ_ASSERT(8 == Foo::numDestroyed); - { - RefPtr<Foo> f = new Foo(); - GetNewFoo(byRef(f)); - MOZ_ASSERT(7 == Foo::numDestroyed); - } + { + RefPtr<Foo> f = new Foo(); + GetPassedFoo(byRef(f)); MOZ_ASSERT(8 == Foo::numDestroyed); + } + MOZ_ASSERT(9 == Foo::numDestroyed); - { - RefPtr<Foo> f = new Foo(); - GetPassedFoo(byRef(f)); - MOZ_ASSERT(8 == Foo::numDestroyed); - } - MOZ_ASSERT(9 == Foo::numDestroyed); - - { - RefPtr<Foo> f = new Foo(); - GetNewFoo(&f); - MOZ_ASSERT(10 == Foo::numDestroyed); - } - MOZ_ASSERT(11 == Foo::numDestroyed); + { + RefPtr<Foo> f = new Foo(); + GetNewFoo(&f); + MOZ_ASSERT(10 == Foo::numDestroyed); + } + MOZ_ASSERT(11 == Foo::numDestroyed); - { - RefPtr<Foo> f = new Foo(); - GetPassedFoo(&f); - MOZ_ASSERT(11 == Foo::numDestroyed); - } - MOZ_ASSERT(12 == Foo::numDestroyed); + { + RefPtr<Foo> f = new Foo(); + GetPassedFoo(&f); + MOZ_ASSERT(11 == Foo::numDestroyed); + } + MOZ_ASSERT(12 == Foo::numDestroyed); - { - RefPtr<Foo> f1 = new Bar(); - } - MOZ_ASSERT(13 == Foo::numDestroyed); + { + RefPtr<Foo> f1 = new Bar(); + } + MOZ_ASSERT(13 == Foo::numDestroyed); - { - RefPtr<Foo> f = GetNullFoo(); - MOZ_ASSERT(13 == Foo::numDestroyed); - } + { + RefPtr<Foo> f = GetNullFoo(); MOZ_ASSERT(13 == Foo::numDestroyed); + } + MOZ_ASSERT(13 == Foo::numDestroyed); - return 0; + return 0; } #endif
--- a/mfbt/Scoped.h +++ b/mfbt/Scoped.h @@ -61,164 +61,164 @@ * typedef value_type type; * // Returns the value corresponding to the uninitialized or freed state * const static type empty(); * // Release resources corresponding to the wrapped value * // This function is responsible for not releasing an |empty| value * const static void release(type); * } */ -template <typename Traits> +template<typename Traits> class Scoped { -public: - typedef typename Traits::type Resource; + public: + typedef typename Traits::type Resource; - explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : value(Traits::empty()) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - explicit Scoped(const Resource& value - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : value(value) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~Scoped() { - Traits::release(value); - } + explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) + : value(Traits::empty()) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } + explicit Scoped(const Resource& value + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : value(value) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } + ~Scoped() { + Traits::release(value); + } - // Constant getter - operator const Resource&() const { return value; } - const Resource& operator->() const { return value; } - const Resource& get() const { return value; } - // Non-constant getter. - Resource& rwget() { return value; } + // Constant getter + operator const Resource&() const { return value; } + const Resource& operator->() const { return value; } + const Resource& get() const { return value; } + // Non-constant getter. + Resource& rwget() { return value; } - /* - * Forget the resource. - * - * Once |forget| has been called, the |Scoped| is neutralized, i.e. it will - * have no effect at destruction (unless it is reset to another resource by - * |operator=|). - * - * @return The original resource. - */ - Resource forget() { - Resource tmp = value; - value = Traits::empty(); - return tmp; - } + /* + * Forget the resource. + * + * Once |forget| has been called, the |Scoped| is neutralized, i.e. it will + * have no effect at destruction (unless it is reset to another resource by + * |operator=|). + * + * @return The original resource. + */ + Resource forget() { + Resource tmp = value; + value = Traits::empty(); + return tmp; + } - /* - * Perform immediate clean-up of this |Scoped|. - * - * If this |Scoped| is currently empty, this method has no effect. - */ - void dispose() { - Traits::release(value); - value = Traits::empty(); - } + /* + * Perform immediate clean-up of this |Scoped|. + * + * If this |Scoped| is currently empty, this method has no effect. + */ + void dispose() { + Traits::release(value); + value = Traits::empty(); + } - bool operator==(const Resource& other) const { - return value == other; - } + bool operator==(const Resource& other) const { + return value == other; + } - /* - * Replace the resource with another resource. - * - * Calling |operator=| has the side-effect of triggering clean-up. If you do - * not want to trigger clean-up, you should first invoke |forget|. - * - * @return this - */ - Scoped<Traits>& operator=(const Resource& other) { - return reset(other); - } - Scoped<Traits>& reset(const Resource& other) { - Traits::release(value); - value = other; - return *this; - } + /* + * Replace the resource with another resource. + * + * Calling |operator=| has the side-effect of triggering clean-up. If you do + * not want to trigger clean-up, you should first invoke |forget|. + * + * @return this + */ + Scoped<Traits>& operator=(const Resource& other) { + return reset(other); + } + Scoped<Traits>& reset(const Resource& other) { + Traits::release(value); + value = other; + return *this; + } -private: - explicit Scoped(const Scoped<Traits>& value) MOZ_DELETE; - Scoped<Traits>& operator=(const Scoped<Traits>& value) MOZ_DELETE; + private: + explicit Scoped(const Scoped<Traits>& value) MOZ_DELETE; + Scoped<Traits>& operator=(const Scoped<Traits>& value) MOZ_DELETE; -private: - Resource value; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER + private: + Resource value; + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; /* * SCOPED_TEMPLATE defines a templated class derived from Scoped * This allows to implement templates such as ScopedFreePtr. * * @param name The name of the class to define. * @param Traits A struct implementing clean-up. See the implementations * for more details. */ #define SCOPED_TEMPLATE(name, Traits) \ -template <typename Type> \ +template<typename Type> \ struct name : public Scoped<Traits<Type> > \ { \ - typedef Scoped<Traits<Type> > Super; \ - typedef typename Super::Resource Resource; \ - name& operator=(Resource ptr) { \ - Super::operator=(ptr); \ - return *this; \ - } \ - explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ - : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ - {} \ - explicit name(Resource ptr \ - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ - : Super(ptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ - {} \ -private: \ - explicit name(name& source) MOZ_DELETE; \ - name& operator=(name& source) MOZ_DELETE; \ + typedef Scoped<Traits<Type> > Super; \ + typedef typename Super::Resource Resource; \ + name& operator=(Resource ptr) { \ + Super::operator=(ptr); \ + return *this; \ + } \ + explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \ + : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \ + {} \ + explicit name(Resource ptr \ + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \ + : Super(ptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \ + {} \ + private: \ + explicit name(name& source) MOZ_DELETE; \ + name& operator=(name& source) MOZ_DELETE; \ }; /* * ScopedFreePtr is a RAII wrapper for pointers that need to be free()d. * * struct S { ... }; * ScopedFreePtr<S> foo = malloc(sizeof(S)); * ScopedFreePtr<char> bar = strdup(str); */ -template <typename T> +template<typename T> struct ScopedFreePtrTraits { - typedef T* type; - static T* empty() { return NULL; } - static void release(T* ptr) { free(ptr); } + typedef T* type; + static T* empty() { return NULL; } + static void release(T* ptr) { free(ptr); } }; SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits) /* * ScopedDeletePtr is a RAII wrapper for pointers that need to be deleted. * * struct S { ... }; * ScopedDeletePtr<S> foo = new S(); */ -template <typename T> -struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T> { - static void release(T* ptr) { delete ptr; } +template<typename T> +struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T> +{ + static void release(T* ptr) { delete ptr; } }; SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits) /* * ScopedDeleteArray is a RAII wrapper for pointers that need to be delete[]ed. * * struct S { ... }; * ScopedDeleteArray<S> foo = new S[42]; */ -template <typename T> +template<typename T> struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T> { - static void release(T* ptr) { delete [] ptr; } + static void release(T* ptr) { delete [] ptr; } }; SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits) - #endif // mozilla_Scoped_h_
--- a/mfbt/StandardInteger.h +++ b/mfbt/StandardInteger.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Implements the C99 <stdint.h> interface for C and C++ code. */ #ifndef mozilla_StandardInteger_h_ #define mozilla_StandardInteger_h_
--- a/mfbt/ThreadLocal.h +++ b/mfbt/ThreadLocal.h @@ -1,13 +1,14 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -// Cross-platform lightweight thread local data wrappers +/* Cross-platform lightweight thread local data wrappers. */ #ifndef mozilla_TLS_h_ #define mozilla_TLS_h_ #if defined(XP_WIN) // This file will get included in any file that wants to add a profiler mark. // In order to not bring <windows.h> together we could include windef.h and // winbase.h which are sufficient to get the prototypes for the Tls* functions. @@ -58,27 +59,27 @@ typedef sig_atomic_t sig_safe_t; * } * * // Set the TLS value * tlsKey.set(123); * * // Get the TLS value * int value = tlsKey.get(); */ -template <typename T> +template<typename T> class ThreadLocal { #if defined(XP_WIN) typedef unsigned long key_t; #else typedef pthread_key_t key_t; #endif union Helper { - void *ptr; + void* ptr; T value; }; public: MOZ_WARN_UNUSED_RESULT inline bool init(); inline T get() const; @@ -88,46 +89,51 @@ class ThreadLocal return inited; } private: key_t key; bool inited; }; -template <typename T> +template<typename T> inline bool -ThreadLocal<T>::init() { - MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *), "mozilla::ThreadLocal can't be used for types larger than a pointer"); +ThreadLocal<T>::init() +{ + MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *), + "mozilla::ThreadLocal can't be used for types larger than " + "a pointer"); MOZ_ASSERT(!initialized()); #ifdef XP_WIN key = TlsAlloc(); inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES #else inited = !pthread_key_create(&key, NULL); #endif return inited; } -template <typename T> +template<typename T> inline T -ThreadLocal<T>::get() const { +ThreadLocal<T>::get() const +{ MOZ_ASSERT(initialized()); Helper h; #ifdef XP_WIN h.ptr = TlsGetValue(key); #else h.ptr = pthread_getspecific(key); #endif return h.value; } -template <typename T> +template<typename T> inline bool -ThreadLocal<T>::set(const T value) { +ThreadLocal<T>::set(const T value) +{ MOZ_ASSERT(initialized()); Helper h; h.value = value; #ifdef XP_WIN return TlsSetValue(key, h.ptr); #else return !pthread_setspecific(key, h.ptr); #endif
--- a/mfbt/Types.h +++ b/mfbt/Types.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* mfbt foundational types and macros. */ #ifndef mozilla_Types_h_ #define mozilla_Types_h_
--- a/mfbt/Util.h +++ b/mfbt/Util.h @@ -1,12 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * Miscellaneous uncategorized functionality. Please add new functionality to * new headers, or to other appropriate existing headers, not here. */ @@ -17,92 +15,88 @@ #include "mozilla/Attributes.h" #include "mozilla/Types.h" #ifdef __cplusplus namespace mozilla { /** - * DebugOnly contains a value of type T, but only in debug builds. In - * release builds, it does not contain a value. This helper is - * intended to be used along with ASSERT()-style macros, allowing one - * to write + * DebugOnly contains a value of type T, but only in debug builds. In release + * builds, it does not contain a value. This helper is intended to be used with + * MOZ_ASSERT()-style macros, allowing one to write: * - * DebugOnly<bool> check = Func(); - * ASSERT(check); + * DebugOnly<bool> check = func(); + * MOZ_ASSERT(check); * - * more concisely than declaring |check| conditional on #ifdef DEBUG, - * but also without allocating storage space for |check| in release - * builds. + * more concisely than declaring |check| conditional on #ifdef DEBUG, but also + * without allocating storage space for |check| in release builds. * - * DebugOnly instances can only be coerced to T in debug builds; in - * release builds, they don't have a value so type coercion is not - * well defined. + * DebugOnly instances can only be coerced to T in debug builds. In release + * builds they don't have a value, so type coercion is not well defined. */ -template <typename T> +template<typename T> struct DebugOnly { #ifdef DEBUG T value; - DebugOnly() {} - DebugOnly(const T& other) : value(other) {} - DebugOnly(const DebugOnly& other) : value(other.value) {} + DebugOnly() { } + DebugOnly(const T& other) : value(other) { } + DebugOnly(const DebugOnly& other) : value(other.value) { } DebugOnly& operator=(const T& rhs) { - value = rhs; - return *this; + value = rhs; + return *this; } void operator++(int) { - value++; + value++; } void operator--(int) { - value--; + value--; } T *operator&() { return &value; } operator T&() { return value; } operator const T&() const { return value; } T& operator->() { return value; } #else - DebugOnly() {} - DebugOnly(const T&) {} - DebugOnly(const DebugOnly&) {} + DebugOnly() { } + DebugOnly(const T&) { } + DebugOnly(const DebugOnly&) { } DebugOnly& operator=(const T&) { return *this; } - void operator++(int) {} - void operator--(int) {} + void operator++(int) { } + void operator--(int) { } #endif /* * DebugOnly must always have a destructor or else it will * generate "unused variable" warnings, exactly what it's intended * to avoid! */ ~DebugOnly() {} }; /* * This class, and the corresponding macro MOZ_ALIGNOF, figure out how many * bytes of alignment a given type needs. */ template<class T> -struct AlignmentFinder +class AlignmentFinder { -private: - struct Aligner - { - char c; - T t; - }; + struct Aligner + { + char c; + T t; + }; -public: - static const int alignment = sizeof(Aligner) - sizeof(T); + public: + static const size_t alignment = sizeof(Aligner) - sizeof(T); }; #define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment /* * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types. * * For instance, @@ -119,216 +113,218 @@ public: # define MOZ_ALIGNED_DECL(_type, _align) \ __declspec(align(_align)) _type #else # warning "We don't know how to align variables on this compiler." # define MOZ_ALIGNED_DECL(_type, _align) _type #endif /* - * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N bytes. + * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N + * bytes. * * We support 1, 2, 4, 8, and 16-bit alignment. */ template<size_t align> struct AlignedElem; /* * We have to specialize this template because GCC doesn't like __attribute__((aligned(foo))) where * foo is a template parameter. */ template<> struct AlignedElem<1> { - MOZ_ALIGNED_DECL(uint8_t elem, 1); + MOZ_ALIGNED_DECL(uint8_t elem, 1); }; template<> struct AlignedElem<2> { - MOZ_ALIGNED_DECL(uint8_t elem, 2); + MOZ_ALIGNED_DECL(uint8_t elem, 2); }; template<> struct AlignedElem<4> { - MOZ_ALIGNED_DECL(uint8_t elem, 4); + MOZ_ALIGNED_DECL(uint8_t elem, 4); }; template<> struct AlignedElem<8> { - MOZ_ALIGNED_DECL(uint8_t elem, 8); + MOZ_ALIGNED_DECL(uint8_t elem, 8); }; template<> struct AlignedElem<16> { - MOZ_ALIGNED_DECL(uint8_t elem, 16); + MOZ_ALIGNED_DECL(uint8_t elem, 16); }; /* * This utility pales in comparison to Boost's aligned_storage. The utility * simply assumes that uint64_t is enough alignment for anyone. This may need * to be extended one day... * * As an important side effect, pulling the storage into this template is * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving * false negatives when we cast from the char buffer to whatever type we've * constructed using the bytes. */ -template <size_t nbytes> +template<size_t nbytes> struct AlignedStorage { union U { - char bytes[nbytes]; - uint64_t _; + char bytes[nbytes]; + uint64_t _; } u; - const void *addr() const { return u.bytes; } - void *addr() { return u.bytes; } + const void* addr() const { return u.bytes; } + void* addr() { return u.bytes; } }; -template <class T> +template<class T> struct AlignedStorage2 { union U { - char bytes[sizeof(T)]; - uint64_t _; + char bytes[sizeof(T)]; + uint64_t _; } u; - const T *addr() const { return (const T *)u.bytes; } - T *addr() { return (T *)(void *)u.bytes; } + const T* addr() const { return reinterpret_cast<const T*>(u.bytes); } + T* addr() { return static_cast<T*>(static_cast<void*>(u.bytes)); } }; /* * Small utility for lazily constructing objects without using dynamic storage. * When a Maybe<T> is constructed, it is |empty()|, i.e., no value of T has * been constructed and no T destructor will be called when the Maybe<T> is * destroyed. Upon calling |construct|, a T object will be constructed with the * given arguments and that object will be destroyed when the owning Maybe<T> * is destroyed. * * N.B. GCC seems to miss some optimizations with Maybe and may generate extra * branches/loads/stores. Use with caution on hot paths. */ -template <class T> +template<class T> class Maybe { AlignedStorage2<T> storage; bool constructed; - T &asT() { return *storage.addr(); } - - explicit Maybe(const Maybe &other); - const Maybe &operator=(const Maybe &other); + T& asT() { return *storage.addr(); } public: Maybe() { constructed = false; } ~Maybe() { if (constructed) asT().~T(); } bool empty() const { return !constructed; } void construct() { - MOZ_ASSERT(!constructed); - new(storage.addr()) T(); - constructed = true; + MOZ_ASSERT(!constructed); + new (storage.addr()) T(); + constructed = true; } - template <class T1> - void construct(const T1 &t1) { - MOZ_ASSERT(!constructed); - new(storage.addr()) T(t1); - constructed = true; + template<class T1> + void construct(const T1& t1) { + MOZ_ASSERT(!constructed); + new (storage.addr()) T(t1); + constructed = true; } - template <class T1, class T2> - void construct(const T1 &t1, const T2 &t2) { - MOZ_ASSERT(!constructed); - new(storage.addr()) T(t1, t2); - constructed = true; + template<class T1, class T2> + void construct(const T1& t1, const T2& t2) { + MOZ_ASSERT(!constructed); + new (storage.addr()) T(t1, t2); + constructed = true; } - template <class T1, class T2, class T3> - void construct(const T1 &t1, const T2 &t2, const T3 &t3) { - MOZ_ASSERT(!constructed); - new(storage.addr()) T(t1, t2, t3); - constructed = true; + template<class T1, class T2, class T3> + void construct(const T1& t1, const T2& t2, const T3& t3) { + MOZ_ASSERT(!constructed); + new (storage.addr()) T(t1, t2, t3); + constructed = true; } - template <class T1, class T2, class T3, class T4> - void construct(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { - MOZ_ASSERT(!constructed); - new(storage.addr()) T(t1, t2, t3, t4); - constructed = true; + template<class T1, class T2, class T3, class T4> + void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { + MOZ_ASSERT(!constructed); + new (storage.addr()) T(t1, t2, t3, t4); + constructed = true; } - T *addr() { - MOZ_ASSERT(constructed); - return &asT(); + T* addr() { + MOZ_ASSERT(constructed); + return &asT(); } - T &ref() { - MOZ_ASSERT(constructed); - return asT(); + T& ref() { + MOZ_ASSERT(constructed); + return asT(); } - const T &ref() const { - MOZ_ASSERT(constructed); - return const_cast<Maybe *>(this)->asT(); + const T& ref() const { + MOZ_ASSERT(constructed); + return const_cast<Maybe*>(this)->asT(); } void destroy() { - ref().~T(); - constructed = false; + ref().~T(); + constructed = false; } void destroyIfConstructed() { - if (!empty()) - destroy(); + if (!empty()) + destroy(); } + + private: + Maybe(const Maybe& other) MOZ_DELETE; + const Maybe& operator=(const Maybe& other) MOZ_DELETE; }; /* * Safely subtract two pointers when it is known that end >= begin. This avoids * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB * set, the unsigned subtraction followed by right shift will produce -1, or * size_t(-1), instead of the real difference. */ -template <class T> +template<class T> MOZ_ALWAYS_INLINE size_t PointerRangeSize(T* begin, T* end) { - MOZ_ASSERT(end >= begin); - return (size_t(end) - size_t(begin)) / sizeof(T); + MOZ_ASSERT(end >= begin); + return (size_t(end) - size_t(begin)) / sizeof(T); } /* * Compute the length of an array with constant length. (Use of this method * with a non-array pointer will not compile.) * * Beware of the implicit trailing '\0' when using this with string constants. */ template<typename T, size_t N> size_t ArrayLength(T (&arr)[N]) { - return N; + return N; } /* * Compute the address one past the last element of a constant-length array. * * Beware of the implicit trailing '\0' when using this with string constants. */ template<typename T, size_t N> T* ArrayEnd(T (&arr)[N]) { - return arr + ArrayLength(arr); + return arr + ArrayLength(arr); } } /* namespace mozilla */ #endif /* __cplusplus */ #endif /* mozilla_Util_h_ */