mfbt/ArrayUtils.h

changeset 0
6474c204b198
     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 */

mercurial