gettimeofday: port recent C++ fix to Emacs
[gnulib.git] / lib / xsize.h
index 42aa68a..4111e0c 100644 (file)
@@ -1,6 +1,6 @@
 /* xsize.h -- Checked size_t computations.
 
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -13,8 +13,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef _XSIZE_H
 #define _XSIZE_H
 # include <stdint.h>
 #endif
 
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef XSIZE_INLINE
+# define XSIZE_INLINE _GL_INLINE
+#endif
+
 /* The size of memory objects is often computed through expressions of
    type size_t. Example:
       void* p = malloc (header_size + n * element_size).
    To avoid this, the functions and macros in this file check for overflow.
    The convention is that SIZE_MAX represents overflow.
    malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
-   implementation that uses mmap --, it's recommended to use SIZE_OVERFLOW_P
-   before invoking malloc().
+   implementation that uses mmap --, it's recommended to use size_overflow_p()
+   or size_in_bounds_p() before invoking malloc().
    The example thus becomes:
       size_t size = xsum (header_size, xtimes (n, element_size));
-      void *p = (!SIZE_OVERFLOW_P (size) ? malloc (size) : NULL);
+      void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
 */
 
 /* Convert an arbitrary value >= 0 to type size_t.  */
   ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
 
 /* Sum of two sizes, with overflow check.  */
-static inline size_t
+XSIZE_INLINE size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
 xsum (size_t size1, size_t size2)
 {
   size_t sum = size1 + size2;
@@ -57,23 +67,41 @@ xsum (size_t size1, size_t size2)
 }
 
 /* Sum of three sizes, with overflow check.  */
-static inline size_t
+XSIZE_INLINE size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
 xsum3 (size_t size1, size_t size2, size_t size3)
 {
   return xsum (xsum (size1, size2), size3);
 }
 
 /* Sum of four sizes, with overflow check.  */
-static inline size_t
+XSIZE_INLINE size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
 xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
 {
   return xsum (xsum (xsum (size1, size2), size3), size4);
 }
 
+/* Maximum of two sizes, with overflow check.  */
+XSIZE_INLINE size_t
+#if __GNUC__ >= 3
+__attribute__ ((__pure__))
+#endif
+xmax (size_t size1, size_t size2)
+{
+  /* No explicit check is needed here, because for any n:
+     max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX.  */
+  return (size1 >= size2 ? size1 : size2);
+}
+
 /* Multiplication of a count with an element size, with overflow check.
    The count must be >= 0 and the element size must be > 0.
-   This is a macro, not an inline function, so that it works correctly even
-   when N is of a wider tupe and N > SIZE_MAX.  */
+   This is a macro, not a function, so that it works correctly even
+   when N is of a wider type and N > SIZE_MAX.  */
 #define xtimes(N, ELSIZE) \
   ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
 
@@ -84,4 +112,6 @@ xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
 #define size_in_bounds_p(SIZE) \
   ((SIZE) != SIZE_MAX)
 
+_GL_INLINE_HEADER_END
+
 #endif /* _XSIZE_H */