1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/ArrayUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* 1.11 + * Implements various helper functions related to arrays. 1.12 + */ 1.13 + 1.14 +#ifndef mozilla_ArrayUtils_h 1.15 +#define mozilla_ArrayUtils_h 1.16 + 1.17 +#include "mozilla/Assertions.h" 1.18 +#include "mozilla/Attributes.h" 1.19 + 1.20 +#include <stddef.h> 1.21 + 1.22 +#ifdef __cplusplus 1.23 + 1.24 +#include "mozilla/Array.h" 1.25 + 1.26 +namespace mozilla { 1.27 + 1.28 +/* 1.29 + * Safely subtract two pointers when it is known that end >= begin. This avoids 1.30 + * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB 1.31 + * set, the unsigned subtraction followed by right shift will produce -1, or 1.32 + * size_t(-1), instead of the real difference. 1.33 + */ 1.34 +template<class T> 1.35 +MOZ_ALWAYS_INLINE size_t 1.36 +PointerRangeSize(T* begin, T* end) 1.37 +{ 1.38 + MOZ_ASSERT(end >= begin); 1.39 + return (size_t(end) - size_t(begin)) / sizeof(T); 1.40 +} 1.41 + 1.42 +/* 1.43 + * Compute the length of an array with constant length. (Use of this method 1.44 + * with a non-array pointer will not compile.) 1.45 + * 1.46 + * Beware of the implicit trailing '\0' when using this with string constants. 1.47 + */ 1.48 +template<typename T, size_t N> 1.49 +MOZ_CONSTEXPR size_t 1.50 +ArrayLength(T (&arr)[N]) 1.51 +{ 1.52 + return N; 1.53 +} 1.54 + 1.55 +template<typename T, size_t N> 1.56 +MOZ_CONSTEXPR size_t 1.57 +ArrayLength(const Array<T, N>& arr) 1.58 +{ 1.59 + return N; 1.60 +} 1.61 + 1.62 +/* 1.63 + * Compute the address one past the last element of a constant-length array. 1.64 + * 1.65 + * Beware of the implicit trailing '\0' when using this with string constants. 1.66 + */ 1.67 +template<typename T, size_t N> 1.68 +MOZ_CONSTEXPR T* 1.69 +ArrayEnd(T (&arr)[N]) 1.70 +{ 1.71 + return arr + ArrayLength(arr); 1.72 +} 1.73 + 1.74 +template<typename T, size_t N> 1.75 +MOZ_CONSTEXPR T* 1.76 +ArrayEnd(Array<T, N>& arr) 1.77 +{ 1.78 + return &arr[0] + ArrayLength(arr); 1.79 +} 1.80 + 1.81 +template<typename T, size_t N> 1.82 +MOZ_CONSTEXPR const T* 1.83 +ArrayEnd(const Array<T, N>& arr) 1.84 +{ 1.85 + return &arr[0] + ArrayLength(arr); 1.86 +} 1.87 + 1.88 +namespace detail { 1.89 + 1.90 +/* 1.91 + * Helper for the MOZ_ARRAY_LENGTH() macro to make the length a typesafe 1.92 + * compile-time constant even on compilers lacking constexpr support. 1.93 + */ 1.94 +template <typename T, size_t N> 1.95 +char (&ArrayLengthHelper(T (&array)[N]))[N]; 1.96 + 1.97 +} /* namespace detail */ 1.98 + 1.99 +} /* namespace mozilla */ 1.100 + 1.101 +#endif /* __cplusplus */ 1.102 + 1.103 +/* 1.104 + * MOZ_ARRAY_LENGTH() is an alternative to mozilla::ArrayLength() for C files 1.105 + * that can't use C++ template functions and for static_assert() calls that 1.106 + * can't call ArrayLength() when it is not a C++11 constexpr function. 1.107 + */ 1.108 +#ifdef __cplusplus 1.109 +# define MOZ_ARRAY_LENGTH(array) sizeof(mozilla::detail::ArrayLengthHelper(array)) 1.110 +#else 1.111 +# define MOZ_ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) 1.112 +#endif 1.113 + 1.114 +#endif /* mozilla_ArrayUtils_h */