diff -r 000000000000 -r 6474c204b198 mfbt/ArrayUtils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mfbt/ArrayUtils.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,111 @@ +/* -*- 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/. */ + +/* + * Implements various helper functions related to arrays. + */ + +#ifndef mozilla_ArrayUtils_h +#define mozilla_ArrayUtils_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include + +#ifdef __cplusplus + +#include "mozilla/Array.h" + +namespace mozilla { + +/* + * 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 +MOZ_ALWAYS_INLINE size_t +PointerRangeSize(T* begin, T* end) +{ + 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 +MOZ_CONSTEXPR size_t +ArrayLength(T (&arr)[N]) +{ + return N; +} + +template +MOZ_CONSTEXPR size_t +ArrayLength(const Array& arr) +{ + 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 +MOZ_CONSTEXPR T* +ArrayEnd(T (&arr)[N]) +{ + return arr + ArrayLength(arr); +} + +template +MOZ_CONSTEXPR T* +ArrayEnd(Array& arr) +{ + return &arr[0] + ArrayLength(arr); +} + +template +MOZ_CONSTEXPR const T* +ArrayEnd(const Array& arr) +{ + return &arr[0] + ArrayLength(arr); +} + +namespace detail { + +/* + * Helper for the MOZ_ARRAY_LENGTH() macro to make the length a typesafe + * compile-time constant even on compilers lacking constexpr support. + */ +template +char (&ArrayLengthHelper(T (&array)[N]))[N]; + +} /* namespace detail */ + +} /* namespace mozilla */ + +#endif /* __cplusplus */ + +/* + * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files + * that can't use C++ template functions and for static_assert() calls that + * can't call ArrayLength() when it is not a C++11 constexpr function. + */ +#ifdef __cplusplus +# define MOZ_ARRAY_LENGTH(array) sizeof(mozilla::detail::ArrayLengthHelper(array)) +#else +# define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) +#endif + +#endif /* mozilla_ArrayUtils_h */