damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

structeq.h (2017B)


      1 /* MIT (BSD) license - see LICENSE file for details */
      2 #ifndef CCAN_STRUCTEQ_H
      3 #define CCAN_STRUCTEQ_H
      4 #include "build_assert.h"
      5 #include "cppmagic.h"
      6 #include <string.h>
      7 #include <stdbool.h>
      8 
      9 /**
     10  * STRUCTEQ_DEF - define an ..._eq function to compare two structures.
     11  * @sname: name of the structure, and function (<sname>_eq) to define.
     12  * @padbytes: number of bytes of expected padding, or negative "max".
     13  * @...: name of every member of the structure.
     14  *
     15  * This generates a single memcmp() call in the common case where the
     16  * structure contains no padding.  Since it can't tell the difference between
     17  * padding and a missing member, @padbytes can be used to assert that
     18  * there isn't any, or how many we expect.  A negative number means
     19  * "up to or equal to that amount of padding", as padding can be
     20  * platform dependent.
     21  */
     22 #define STRUCTEQ_DEF(sname, padbytes, ...)                \
     23 static inline bool CPPMAGIC_GLUE2(sname, _eq)(const struct sname *_a, \
     24                           const struct sname *_b) \
     25 {                                    \
     26     BUILD_ASSERT(((padbytes) < 0 &&                    \
     27               CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \
     28                             __VA_ARGS__))    \
     29               - (padbytes) >= sizeof(*_a))            \
     30              || CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \
     31                               __VA_ARGS__))    \
     32              + (padbytes) == sizeof(*_a));            \
     33     if (CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, __VA_ARGS__)) \
     34         == sizeof(*_a))                        \
     35         return memcmp(_a, _b, sizeof(*_a)) == 0;        \
     36     else                                \
     37         return CPPMAGIC_JOIN(&&,                \
     38                      CPPMAGIC_MAP(STRUCTEQ_MEMBER_CMP_, \
     39                           __VA_ARGS__));    \
     40 }
     41 
     42 /* Helpers */
     43 #define STRUCTEQ_MEMBER_SIZE_(m) sizeof((_a)->m)
     44 #define STRUCTEQ_MEMBER_CMP_(m) memcmp(&_a->m, &_b->m, sizeof(_a->m)) == 0
     45 
     46 #endif /* CCAN_STRUCTEQ_H */