Skip to content

Instantly share code, notes, and snippets.

@Eczbek
Last active June 7, 2026 02:20
Show Gist options
  • Select an option

  • Save Eczbek/1465181a29406f89ce507b366bfc5933 to your computer and use it in GitHub Desktop.

Select an option

Save Eczbek/1465181a29406f89ce507b366bfc5933 to your computer and use it in GitHub Desktop.
generic-ish swap
#ifndef DETAIL_META_HEADER_SWAP
#define DETAIL_META_HEADER_SWAP
#include <stddef.h>
#include <string.h>
// Assigns each variable to the other's value.
// If the variables have different types, each is cast to the other's type before assignment.
#define meta_swap(A, B) \
((void)_Generic(typeof_unqual(A), typeof_unqual(B): meta_swap(true, &(A), &(B), &(char[sizeof(A)]){}, sizeof(A)), default: _Generic(typeof_unqual(A), typeof_unqual(B): (int){}, default: (A)) = (typeof(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (A)))){ (typeof(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (A))))*(typeof(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (B)))*)meta_swap(false, &(B), &(typeof(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (B)))){ (typeof(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (B))))(_Generic(typeof_unqual(A), typeof_unqual(B): 0, default: (A))) }, &(char[sizeof(B)]){}, sizeof(B)) }))
static inline void* (meta_swap)(bool same, void* a, void* b, void* buffer, size_t size) {
memcpy(buffer, a, size);
memcpy(a, b, size);
if (same) {
memcpy(b, buffer, size);
}
return buffer;
}
#endif
#include <stdio.h>
typedef struct {
int x;
char y;
} A;
int main() {
int x = 1;
double y = 2.0;
meta_swap(x, y);
printf("%i <-> %lf\n", x, y);
A a = { 1, 2 };
A b = { 3, 4 };
meta_swap(a, b);
printf("(%i, %i) <-> (%i, %i)\n", a.x, a.y, b.x, b.y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment