LCOV - code coverage report
Current view: top level - src/include/utils - relptr.h (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 4 4 100.0 %
Date: 2024-11-21 08:14:44 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * relptr.h
       4             :  *    This file contains basic declarations for relative pointers.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  * src/include/utils/relptr.h
      10             :  *
      11             :  *-------------------------------------------------------------------------
      12             :  */
      13             : 
      14             : #ifndef RELPTR_H
      15             : #define RELPTR_H
      16             : 
      17             : /*
      18             :  * Relative pointers are intended to be used when storing an address that may
      19             :  * be relative either to the base of the process's address space or some
      20             :  * dynamic shared memory segment mapped therein.
      21             :  *
      22             :  * The idea here is that you declare a relative pointer as relptr(type)
      23             :  * and then use relptr_access to dereference it and relptr_store to change
      24             :  * it.  The use of a union here is a hack, because what's stored in the
      25             :  * relptr is always a Size, never an actual pointer.  But including a pointer
      26             :  * in the union allows us to use stupid macro tricks to provide some measure
      27             :  * of type-safety.
      28             :  */
      29             : #define relptr(type)     union { type *relptr_type; Size relptr_off; }
      30             : 
      31             : /*
      32             :  * pgindent gets confused by declarations that use "relptr(type)" directly,
      33             :  * so preferred style is to write
      34             :  *      typedef struct ... SomeStruct;
      35             :  *      relptr_declare(SomeStruct, RelptrSomeStruct);
      36             :  * and then declare pointer variables as "RelptrSomeStruct someptr".
      37             :  */
      38             : #define relptr_declare(type, relptrtype) \
      39             :     typedef relptr(type) relptrtype
      40             : 
      41             : #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
      42             : #define relptr_access(base, rp) \
      43             :     (AssertVariableIsOfTypeMacro(base, char *), \
      44             :      (__typeof__((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \
      45             :         (base) + (rp).relptr_off - 1))
      46             : #else
      47             : /*
      48             :  * If we don't have __builtin_types_compatible_p, assume we might not have
      49             :  * __typeof__ either.
      50             :  */
      51             : #define relptr_access(base, rp) \
      52             :     (AssertVariableIsOfTypeMacro(base, char *), \
      53             :      (void *) ((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1))
      54             : #endif
      55             : 
      56             : #define relptr_is_null(rp) \
      57             :     ((rp).relptr_off == 0)
      58             : 
      59             : #define relptr_offset(rp) \
      60             :     ((rp).relptr_off - 1)
      61             : 
      62             : /* We use this inline to avoid double eval of "val" in relptr_store */
      63             : static inline Size
      64      710036 : relptr_store_eval(char *base, char *val)
      65             : {
      66      710036 :     if (val == NULL)
      67      672660 :         return 0;
      68             :     else
      69             :     {
      70             :         Assert(val >= base);
      71       37376 :         return val - base + 1;
      72             :     }
      73             : }
      74             : 
      75             : #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
      76             : #define relptr_store(base, rp, val) \
      77             :     (AssertVariableIsOfTypeMacro(base, char *), \
      78             :      AssertVariableIsOfTypeMacro(val, __typeof__((rp).relptr_type)), \
      79             :      (rp).relptr_off = relptr_store_eval((base), (char *) (val)))
      80             : #else
      81             : /*
      82             :  * If we don't have __builtin_types_compatible_p, assume we might not have
      83             :  * __typeof__ either.
      84             :  */
      85             : #define relptr_store(base, rp, val) \
      86             :     (AssertVariableIsOfTypeMacro(base, char *), \
      87             :      (rp).relptr_off = relptr_store_eval((base), (char *) (val)))
      88             : #endif
      89             : 
      90             : #define relptr_copy(rp1, rp2) \
      91             :     ((rp1).relptr_off = (rp2).relptr_off)
      92             : 
      93             : #endif                          /* RELPTR_H */

Generated by: LCOV version 1.14