Fast swap for C
fswap.h
Go to the documentation of this file.
1 //--------------------------------------------------------------------------------------
2 //
3 // Fast swap for C
4 // inspire: https://ru.stackoverflow.com/questions/836089/%d0%9e%d0%b1%d0%bc%d0%b5%d0%bd-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d1%83%d0%ba%d0%b0%d0%b7%d0%b0%d1%82%d0%b5%d0%bb%d0%b8/836167#836167
5 // online example: http://coliru.stacked-crooked.com/a/be12a57be0162860
6 // require: GCC
7 // build example: gcc --std=gnu99 -O2 -Wall -pedantic -funit-at-a-time swap-test.c ; ./a.out
8 // Copyright (C) 2018, @PS
9 //
10 // - https://github.com/PetersSharp/Fast-Swap-for-C
11 //
12 // * $Id$
13 // * commit date: $Format:%cd by %aN$
14 //
15 //--------------------------------------------------------------------------------------
16 
17 #ifndef FAST_SWAP_H
18 #define FAST_SWAP_H
19 
88 #define __swap_fast(A,B) __extension__ \
89  (__builtin_choose_expr( \
90  __builtin_types_compatible_p(__typeof__(A), int[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
91  __builtin_choose_expr( \
92  __builtin_types_compatible_p(__typeof__(A), const int[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
93  __builtin_choose_expr( \
94  __builtin_types_compatible_p(__typeof__(A), unsigned int[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
95  __builtin_choose_expr( \
96  __builtin_types_compatible_p(__typeof__(A), const unsigned int[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
97  __builtin_choose_expr( \
98  __builtin_types_compatible_p(__typeof__(A), short[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
99  __builtin_choose_expr( \
100  __builtin_types_compatible_p(__typeof__(A), const short[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
101  __builtin_choose_expr( \
102  __builtin_types_compatible_p(__typeof__(A), unsigned short[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
103  __builtin_choose_expr( \
104  __builtin_types_compatible_p(__typeof__(A), const unsigned short[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
105  __builtin_choose_expr( \
106  __builtin_types_compatible_p(__typeof__(A), long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
107  __builtin_choose_expr( \
108  __builtin_types_compatible_p(__typeof__(A), const long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
109  __builtin_choose_expr( \
110  __builtin_types_compatible_p(__typeof__(A), unsigned long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
111  __builtin_choose_expr( \
112  __builtin_types_compatible_p(__typeof__(A), const unsigned long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
113  __builtin_choose_expr( \
114  __builtin_types_compatible_p(__typeof__(A), long long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
115  __builtin_choose_expr( \
116  __builtin_types_compatible_p(__typeof__(A), const long long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
117  __builtin_choose_expr( \
118  __builtin_types_compatible_p(__typeof__(A), unsigned long long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
119  __builtin_choose_expr( \
120  __builtin_types_compatible_p(__typeof__(A), unsigned const long long[]), __swap_p(A, B, sizeof(A), sizeof(B)), \
121  __builtin_choose_expr( \
122  __builtin_types_compatible_p(__typeof__(A), char*), __swap_pp((void**)&A, (void**)&B), \
123  __builtin_choose_expr( \
124  __builtin_types_compatible_p(__typeof__(A), const char*), __swap_pp((void**)&A, (void**)&B), \
125  __builtin_choose_expr( \
126  __builtin_types_compatible_p(__typeof__(A), char[]), __swap_p(A, B, (sizeof(A) - 1), (sizeof(B) - 1)), \
127  __builtin_choose_expr( \
128  __builtin_types_compatible_p(__typeof__(A), const char[]), __swap_p(A, B, (sizeof(A) - 1), (sizeof(B) - 1)), \
129  __builtin_choose_expr( \
130  __builtin_types_compatible_p(__typeof__(A), unsigned char*), __swap_pp((void**)&A, (void**)&B), \
131  __builtin_choose_expr( \
132  __builtin_types_compatible_p(__typeof__(A), const unsigned char*), __swap_pp((void**)&A, (void**)&B), \
133  __builtin_choose_expr( \
134  __builtin_types_compatible_p(__typeof__(A), unsigned char[]), __swap_p(A, B, (sizeof(A) - 1), (sizeof(B) - 1)), \
135  __builtin_choose_expr( \
136  __builtin_types_compatible_p(__typeof__(A), const unsigned char[]), __swap_p(A, B, (sizeof(A) - 1), (sizeof(B) - 1)), \
137  __builtin_choose_expr( \
138  __builtin_types_compatible_p(__typeof__(A), void*), __swap_pp((void**)&A, (void**)&B), \
139  __builtin_choose_expr( \
140  __builtin_types_compatible_p(__typeof__(A), const void*), __swap_pp((void**)&A, (void**)&B), \
141  __builtin_choose_expr( \
142  __builtin_types_compatible_p(__typeof__(A), void*[]), __swap_ppp((void***)&A, (void***)&B), \
143  __builtin_choose_expr( \
144  __builtin_types_compatible_p(__typeof__(A), const void*[]), __swap_ppp((void***)&A, (void***)&B), \
145  __swap_p(A, B, sizeof(*A), sizeof(*B)))))))))))))))))))))))))))))))
146 
156 __attribute__((always_inline)) inline void __swap_ppp(void ***a, void ***b)
157 {
158  void **c = *a;
159  *a = *b; *b = c;
160 }
161 
171 __attribute__((always_inline)) inline void __swap_pp(void **a, void **b)
172 {
173  void *c = *a;
174  *a = *b; *b = c;
175 }
176 
189 __attribute__((always_inline)) inline void __swap_p(void *a, void *b, size_t na, size_t nb)
190 {
191  if ((!na) || (na != nb)) { return; }
192 
193  char *va = (char*)a,
194  *vb = (char*)b;
195 
196  if (va == vb) { return; }
197 
198  __builtin_prefetch(va + na, 1, 1);
199  __builtin_prefetch(vb + nb, 1, 1);
200 
201  while (na--)
202  {
203  va[na] ^= vb[na];
204  vb[na] ^= va[na];
205  va[na] ^= vb[na];
206  }
207 }
208 
209 #endif
void __swap_ppp(void ***a, void ***b)
Swap triple pointers types.
Definition: fswap.h:156
void __swap_p(void *a, void *b, size_t na, size_t nb)
Swap all sized types.
Definition: fswap.h:189
void __swap_pp(void **a, void **b)
Swap double pointers types.
Definition: fswap.h:171