damus

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

structeq.h (1779B)


      1 /* MIT (BSD) license - see LICENSE file for details */
      2 #ifndef CCAN_STRUCTEQ_H
      3 #define CCAN_STRUCTEQ_H
      4 #include <ccan/build_assert/build_assert.h>
      5 #include <ccan/cppmagic/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 */