gvec.h
复制内容到剪贴板
代码:
/*
Copyright (c) 2006, emacsnw
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GVEC_H_
#define _GVEC_H_
#include <stdio.h>
#include <stdlib.h>
#define VEC_DECLARE(type)\
struct _VEC_##type{\
int vsize,asize;\
type *x;\
};\
typedef struct _VEC_##type VEC_##type
#define vec(type) VEC_##type
#define vec2(type) VEC_VEC_##type
VEC_DECLARE(int);
VEC_DECLARE(double);
VEC_DECLARE(char);
VEC_DECLARE(float);
VEC_DECLARE(VEC_int);
VEC_DECLARE(VEC_double);
VEC_DECLARE(VEC_char);
VEC_DECLARE(VEC_float);
#define _swap(type,a,b)\
do{\
type _sw_tmp;\
_sw_tmp = a,a = b,b = _sw_tmp;\
}while(0)
#define vec_append(type,des,src)\
do{\
int _co_i,_co_m = src.vsize;\
for(_co_i = 0;_co_i<_co_m;++_co_i) vec_push(type,des,src.x[_co_i]);\
}while(0)
#define vec2_append(type,des,src)\
do{\
int _co__i,_co__m = src.vsize;\
for(_co__i = 0;_co__i<_co__m;++_co__i) vec2_push(type,des,src.x[_co__i]);\
}while(0)
#define vec_back(type,v,y) y = vec_top(type,v)
#define vec2_back(type,v,y) vec_cpy(type,y,vec2_top(type,v))
#define _vec_bsearch(v,y,ret)\
do{\
int _bs_l = 0,_bs_r = v.vsize,_bs_m;\
while(_bs_l<_bs_r){\
_bs_m = (_bs_l+_bs_r)>>1;\
if(v.x[_bs_m]<y) _bs_l = _bs_m+1;\
else if(v.x[_bs_m]>y) _bs_r = _bs_m;\
else{\
ret = _bs_m;\
break;\
}\
}\
ret = _bs_l;\
}while(0)
#define vec_bsearch(type,v,y,ret) _vec_bsearch(v,y,ret)
#define vec_clear(type,v)\
do{\
vec_free(type,v);\
vec_init(type,v);\
}while(0)
#define vec2_clear(type,v)\
do{\
vec2_free(type,v);\
vec2_init(type,v);\
}while(0)
#define vec_cpy(type,des,src)\
do{\
vec_free(type,des);\
vec_initc(type,des,src);\
}while(0)
#define vec2_cpy(type,des,src)\
do{\
vec2_free(type,des);\
vec2_initc(type,des,src);\
}while(0)
#define vec_del(type,v,idx)\
do{\
v.x[idx] = v.x[v.vsize-1];\
vec_reducelength(type,v,1);\
}while(0)
#define vec2_del(type,v,idx)\
do{\
vec_cpy(type,v.x[idx],v.x[v.vsize-1]);\
vec2_reducelength(type,v,1);\
}while(0)
#define vec_deque(type,v,y) vec_popfront(type,v,y)
#define vec2_deque(type,v,y) vec2_popfront(type,v,y)
#define _vec_empty(v) (v.vsize==0)
#define vec_empty(type,v) _vec_empty(v)
#define _vec2_empty(v) _vec_empty(v)
#define vec2_empty(type,v) _vec2_empty(v)
#define vec_enque(type,v,y) vec_pushback(type,v,y)
#define vec2_enque(type,v,y) vec2_pushback(type,v,y)
#define vec_equal(type,v,u,ret)\
do{\
int _eq_i,_eq_m = v.vsize;\
ret = 0;\
if(_eq_m!=u.vsize) break;\
for(_eq_i = 0;_eq_i<_eq_m;++_eq_i)\
if(v.x[_eq_i]!=u.x[_eq_i]) break;\
if(_eq_i==_eq_m) ret = 1;\
}while(0)
#define vec2_equal(type,v,u,ret)\
do{\
int _eq__i,_eq__ret,_eq__m = v.vsize;\
ret = 0;\
if(_eq__m!=u.vsize) break;\
for(_eq__i = 0;_eq__i<_eq__m;++_eq__i){\
vec_equal(type,v.x[_eq__i],u.x[_eq__i],_eq__ret);\
if(_eq__ret==0) break;\
}\
if(_eq__i==_eq__m) ret = 1;\
}while(0)
#define _vec_find(v,y,ret)\
do{\
int _fi_i,_fi_m = v.vsize;\
ret = -1;\
for(_fi_i = 0;_fi_i<_fi_m;++_fi_i)\
if(v.x[_fi_i]==y){\
ret = _fi_i;\
break;\
}\
}while(0)
#define vec_find(type,v,y,ret) _vec_find(v,y,ret)
#define vec2_find(type,v,y,ret)\
do{\
int _fi__i,_fi__ret,_fi__m = v.vsize;\
ret = -1;\
for(_fi__i = 0;_fi__i<_fi__m;++_fi__i){\
vec_equal(type,v.x[_fi__i],y,_fi__ret);\
if(_fi__ret){\
ret = _fi__i;\
break;\
}\
}\
}while(0)
#define _vec_free(v)\
do{\
if(v.asize) free(v.x);\
v.vsize = v.asize = 0;\
}while(0)
#define vec_free(type,v) _vec_free(v)
#define _vec2_free(v)\
do{\
int _fr__i,_fr__m = v.vsize;\
for(_fr__i = 0;_fr__i<_fr__m;++_fr__i) _vec_free(v.x[_fr__i]);\
if(v.asize) free(v.x);\
v.vsize = v.asize = 0;\
}while(0)
#define vec2_free(type,v) _vec2_free(v)
#define vec_front(type,v,y)\
do{\
if(!vec_empty(type,v)) y = v.x[0];\
}while(0)
#define vec2_front(type,v,y)\
do{\
if(!vec2_empty(type,v)) vec_cpy(type,y,v.x[0]);\
}while(0)
#define vec_init(type,v)\
do{\
v.vsize = 0,v.asize = 10;\
v.x = (type *)malloc(v.asize*sizeof(type));\
}while(0)
#define vec2_init(type,v)\
do{\
v.vsize = 0,v.asize = 10;\
v.x = (VEC_##type *)malloc(v.asize*sizeof(VEC_##type));\
}while(0)
#define vec_initc(type,v,y)\
do{\
int _ci_i,_ci_m = y.vsize;\
v.vsize = _ci_m;\
if(_ci_m==0) v.asize = 10;\
else v.asize = _ci_m;\
v.x = (type *)malloc(v.asize*sizeof(type));\
for(_ci_i = 0;_ci_i<_ci_m;++_ci_i) v.x[_ci_i] = y.x[_ci_i];\
}while(0)
#define vec2_initc(type,v,y)\
do{\
int _ci__i,_ci__m = y.vsize;\
v.vsize = _ci__m;\
if(_ci__m==0) v.asize = 10;\
else v.asize = _ci__m;\
v.x = (VEC_##type *)malloc(v.asize*sizeof(VEC_##type));\
for(_ci__i = 0;_ci__i<_ci__m;++_ci__i) vec_initc(type,v.x[_ci__i],y.x[_ci__i]);\
}while(0)
#define vec_initn(type,v,n,y)\
do{\
int _ni_i;\
v.vsize = v.asize = (n);\
v.x = (type *)malloc((n)*sizeof(type));\
for(_ni_i = 0;_ni_i<(n);++_i) v.x[_ni_i] = (y);\
}while(0)
#define vec2_initn(type,v,n,y)\
do{\
int _ni__i;\
v.vsize = v.asize = (n);\
v.x = (VEC_##type *)malloc((n)*sizeof(VEC_##type));\
for(_ni__i = 0;_ni__i<(n);++_ni__i) vec_initc(type,v.x[_ni__i],y);\
}while(0)
#define vec_insert(type,v,y,idx)\
do{\
int _in_i,_in_m = v.vsize,_in_idx = (idx);\
if(_in_idx>_in_m) _in_idx = _in_m;\
vec_push(type,v,y);\
for(_in_i = _in_m;_in_i>_in_idx;--_in_i) _swap(type,v.x[_in_i],v.x[_in_i-1]);\
}while(0)
#define vec2_insert(type,v,y,idx)\
do{\
int _in__i,_in__m = v.vsize,_in__idx = (idx);\
if(_in__idx>_in__m) _in__idx = _in__m;\
vec2_push(type,v,y);\
for(_in__i = _in__m;_in__i>_in__idx;--_in__i) vec_swap(type,v.x[_in__i],v.x[_in__i-1]);\
}while(0)
#define _vec_length(v) v.vsize
#define vec_length(type,v) _vec_length(v)
#define _vec2_length(v) _vec_length(v)
#define vec2_length(type,v) _vec2_length(v)
#define vec_pop(type,v,y)\
do{\
if(!vec_empty(type,v)){\
y = vec_top(type,v);\
vec_reducelength(type,v,1);\
}\
}while(0)
#define vec2_pop(type,v,y)\
do{\
if(!vec2_empty(type,v)){\
y = vec2_top(type,v);\
vec2_reducelength(type,v,1);\
}\
}while(0)
#define vec_popback(type,v,y) vec_pop(type,v,y)
#define vec2_popback(type,v,y) vec2_pop(type,v,y)
#define vec_popfront(type,v,y)\
do{\
if(!vec_empty(type,v)){\
vec_front(type,v,y);\
vec_remove(type,v,0);\
}\
}while(0)
#define vec2_popfront(type,v,y)\
do{\
if(!vec2_empty(type,v)){\
vec2_front(type,v,y);\
vec2_remove(type,v,0);\
}\
}while(0)
#define _vec_printf(v,fmt)\
do{\
int _pr_i,_pr_m = v.vsize;\
printf("%d",_pr_m);\
for(_pr_i = 0;_pr_i<_pr_m;++_pr_i) printf(" "fmt,v.x[_pr_i]);\
printf("\n");\
}while(0)
#define vec_printf(type,v,fmt) _vec_printf(v,fmt)
#define _vec2_printf(v,fmt)\
do{\
int _pr__i,_pr__m = v.vsize;\
printf("%d\n",_pr__m);\
for(_pr__i = 0;_pr__i<_pr__m;++_pr__i) _vec_printf(v.x[_pr__i],fmt);\
}while(0)
#define vec2_printf(type,v,fmt) _vec2_printf(v,fmt)
#define vec_push(type,v,y)\
do{\
int _pu_i,_pu_nasize,_pu_m = v.vsize;\
type *_pu_nx;\
if(_pu_m<v.asize){\
v.x[_pu_m] = y;\
v.vsize++;\
}else{\
_pu_nasize = v.asize * 2;\
_pu_nx = (type *)malloc(_pu_nasize*sizeof(type));\
for(_pu_i = 0;_pu_i<_pu_m;++_pu_i) _pu_nx[_pu_i] = v.x[_pu_i];\
_pu_nx[_pu_m] = y;\
free(v.x);\
v.x = _pu_nx;\
v.vsize = _pu_m+1;\
v.asize = _pu_nasize;\
}\
}while(0)
#define vec2_push(type,v,y)\
do{\
int _pu__i,_pu__nasize,_pu__m = v.vsize;\
VEC_##type *_pu__nx;\
if(_pu__m<v.asize){\
vec_initc(type,v.x[_pu__m],y);\
v.vsize++;\
}else{\
_pu__nasize = v.asize * 2;\
_pu__nx = (VEC_##type *)malloc(_pu__nasize*sizeof(VEC_##type));\
for(_pu__i = 0;_pu__i<_pu__m;++_pu__i) vec_initc(type,_pu__nx[_pu__i],v.x[_pu__i]);\
vec_initc(type,_pu__nx[_pu__m],y);\
vec2_free(type,v);\
v.x = _pu__nx;\
v.vsize = _pu__m+1;\
v.asize = _pu__nasize;\
}\
}while(0)
#define vec_pushback(type,v,y) vec_push(type,v,y)
#define vec2_pushback(type,v,y) vec2_push(type,v,y)
#define vec_pushfront(type,v,y) vec_insert(type,v,y,0)
#define vec2_pushfront(type,v,y) vec2_insert(type,v,y,0)
#define vec_reducelength(type,v,by)\
do{\
int _re_i,_re_nasize,_re_m = v.vsize-(by);\
type *_re_nx;\
if((by)==0) break;\
if(_re_m<=v.asize/2){\
for(_re_nasize = v.asize;_re_nasize/2>=_re_m && _re_nasize>3;_re_nasize /= 2);\
_re_nx = (type *)malloc(_re_nasize*sizeof(type));\
for(_re_i = 0;_re_i<_re_m;++_re_i) _re_nx[_re_i] = v.x[_re_i];\
free(v.x);\
v.x = _re_nx;\
v.asize = _re_nasize;\
}\
v.vsize = _re_m;\
}while(0)
#define vec2_reducelength(type,v,by)\
do{\
int _re__i,_re__nasize,_re__m = v.vsize-(by);\
VEC_##type *_re__nx;\
if((by)==0) break;\
if(_re__m>v.asize/2){\
for(_re__i = _re__m;_re__i<v.vsize;++_re__i) vec_free(type,v.x[_re__i]);\
v.vsize = _re__m;\
}else{\
for(_re__nasize = v.asize;_re__nasize/2>=_re__m && _re__nasize>3;_re__nasize /= 2);\
_re__nx = (VEC_##type *)malloc(_re__nasize*sizeof(VEC_##type));\
for(_re__i = 0;_re__i<_re__m;++_re__i) vec_initc(type,_re__nx[_re__i],v.x[_re__i]);\
vec2_free(type,v);\
v.x = _re__nx;\
v.vsize = _re__m;\
v.asize = _re__nasize;\
}\
}while(0)
#define vec_remove(type,v,idx)\
do{\
int _rm_i,_rm_m = v.vsize;\
for(_rm_i = idx;_rm_i<_rm_m-1;++_rm_i) v.x[_rm_i] = v.x[_rm_i+1];\
vec_reducelength(type,v,1);\
}while(0)
#define vec2_remove(type,v,idx)\
do{\
int _rm__i,_rm__m = v.vsize;\
for(_rm__i = idx;_rm__i<_rm__m-1;++_rm__i) vec_cpy(type,v.x[_rm__i],v.x[_rm__i+1]);\
vec2_reducelength(type,v,1);\
}while(0)
#define vec_replace(type,v,a,b)\
do{\
int _rp_i,_rp_m = v.vsize;\
for(_rp_i = 0;_rp_i<_rp_m;++_rp_i)\
if(v.x[_rp_i]==(a)) v.x[_rp_i] = (b);\
}while(0)
#define vec2_replace(type,v,a,b)\
do{\
int _rp__i,_rp__ret,_rp__m = v.vsize;\
for(_rp__i = 0;_rp__i<_rp__m;++_rp__i){\
vec_equal(type,v.x[_rp__i],a,_rp__ret);\
if(_rp__ret) vec_cpy(type,v.x[_rp__i],b);\
}\
}while(0)
#define vec_reverse(type,v)\
do{\
int _rv_i,_rv_m = v.vsize,_rv_mid = _rv_m/2;\
if(_rv_m<=1) break;\
for(_rv_i = 0;_rv_i<_rv_mid;++_rv_i) _swap(type,v.x[_rv_i],v.x[_rv_m-_rv_i-1]);\
}while(0)
#define vec2_reverse(type,v)\
do{\
int _rv__i,_rv__m = v.vsize,_rv__mid = _rv__m/2;\
if(_rv__m<=1) break;\
for(_rv__i = 0;_rv__i<_rv__mid;++_rv__i) vec_swap(type,v.x[_rv__i],v.x[_rv__m-_rv__i-1]);\
}while(0)
#define vec_save(type,v,fmt) vec_printf(type,v,fmt)
#define vec2_save(type,v,fmt) vec2_printf(type,v,fmt)
#define vec_scanf(type,v,fmt)
#define vec_setlength(type,v,l,y)\
do{\
int _se_i,_se_nasize,_se_m = v.vsize;\
type *_se_nx;\
if((l)<=_se_m) vec_reducelength(type,v,_se_m-(l));\
else if((l)<=v.asize){\
for(_se_i = _se_m;_se_i<(l);++_se_i) v.x[_se_i] = y;\
v.vsize = (l);\
}else{\
for(_se_nasize = v.asize;_se_nasize<(l);_se_nasize *= 2);\
_se_nx = (type *)malloc(_se_nasize*sizeof(type));\
for(_se_i = 0;_se_i<_se_m;++_se_i) _se_nx[_se_i] = v.x[_se_i];\
for(_se_i = _se_m;_se_i<(l);++_se_i) _se_nx[_se_i] = y;\
free(v.x);\
v.vsize = (l);\
v.asize = _se_nasize;\
v.x = _se_nx;\
}\
}while(0)
#define vec2_setlength(type,v,l,y)\
do{\
int _se__i,_se__nasize,_se__m = v.vsize;\
VEC_##type *_se__nx;\
if((l)<=_se__m) vec2_reducelength(type,v,_se__m-(l));\
else if((l)<=v.asize){\
for(_se__i = _se__m;_se__i<(l);++_se__i) vec_initc(type,v.x[_se__i],y);\
v.vsize = (l);\
}else{\
for(_se__nasize = v.asize;_se__nasize<(l);_se__nasize *= 2);\
_se__nx = (VEC_##type *)malloc(_se__nasize*sizeof(VEC_##type));\
for(_se__i = 0;_se__i<_se__m;++_se__i) vec_initc(type,_se__nx[_se__i],v.x[_se__i]);\
for(_se__i = _se__m;_se__i<(l);++_se__i) vec_initc(type,_se__nx[_se__i],y);\
vec2_free(type,v);\
v.vsize = (l);\
v.asize = _se__nasize;\
v.x = _se__nx;\
}\
}while(0)复制内容到剪贴板
代码:
#define vec_sort(type,v,_op_)\
do{\
int _so_i,_so_ir = v.vsize-1,_so_j,_so_k,_so_l = 0,_so_istack[50],_so_jstack = -1;\
type _so_a;\
for(;;){\
if(_so_ir-_so_l<7){\
for(_so_j = _so_l+1;_so_j<=_so_ir;++_so_j){\
_so_a = v.x[_so_j];\
for(_so_i = _so_j-1;_so_i>=_so_l;--_so_i){\
if(!(_so_a _op_ v.x[_so_i])) break;\
v.x[_so_i+1] = v.x[_so_i];\
}\
v.x[_so_i+1] = _so_a;\
}\
if(_so_jstack==-1) break;\
_so_ir = _so_istack[_so_jstack];\
_so_l = _so_istack[_so_jstack-1];\
_so_jstack -= 2;\
}else{\
_so_k = (_so_l+_so_ir)>>1;\
_swap(type,v.x[_so_k],v.x[_so_l+1]);\
if(v.x[_so_ir] _op_ v.x[_so_l]) _swap(type,v.x[_so_l],v.x[_so_ir]);\
if(v.x[_so_ir] _op_ v.x[_so_l+1]) _swap(type,v.x[_so_l+1],v.x[_so_ir]);\
if(v.x[_so_l+1] _op_ v.x[_so_l]) _swap(type,v.x[_so_l],v.x[_so_l+1]);\
_so_i = _so_l+1,_so_j = _so_ir;\
_so_a = v.x[_so_l+1];\
for(;;){\
do ++_so_i; while(v.x[_so_i] _op_ _so_a);\
do --_so_j; while(_so_a _op_ v.x[_so_j]);\
if(_so_j<_so_i) break;\
_swap(type,v.x[_so_i],v.x[_so_j]);\
}\
v.x[_so_l+1] = v.x[_so_j];\
v.x[_so_j] = _so_a;\
_so_jstack += 2;\
if(_so_ir-_so_i+1>=_so_j-_so_l){\
_so_istack[_so_jstack] = _so_ir;\
_so_istack[_so_jstack-1] = _so_i;\
_so_ir = _so_j-1;\
}else{\
_so_istack[_so_jstack] = _so_j-1;\
_so_istack[_so_jstack-1] = _so_l;\
_so_l = _so_i;\
}\
}\
}\
}while(0)
#define vec_sortp(type,v,typeu,u,_op_)\
do{\
int _so_i,_so_ir = v.vsize-1,_so_j,_so_k,_so_l = 0,_so_istack[50],_so_jstack = -1;\
type _so_a;\
typeu _so_b;\
for(;;){\
if(_so_ir-_so_l<7){\
for(_so_j = _so_l+1;_so_j<=_so_ir;++_so_j){\
_so_a = v.x[_so_j];\
_so_b = u.x[_so_j];\
for(_so_i = _so_j-1;_so_i>=_so_l;--_so_i){\
if(!(_so_a _op_ v.x[_so_i])) break;\
v.x[_so_i+1] = v.x[_so_i];\
u.x[_so_i+1] = u.x[_so_i];\
}\
v.x[_so_i+1] = _so_a;\
u.x[_so_i+1] = _so_b;\
}\
if(_so_jstack==-1) break;\
_so_ir = _so_istack[_so_jstack];\
_so_l = _so_istack[_so_jstack-1];\
_so_jstack -= 2;\
}else{\
_so_k = (_so_l+_so_ir)>>1;\
_swap(type,v.x[_so_k],v.x[_so_l+1]);\
_swap(typeu,u.x[_so_k],u.x[_so_l+1]);\
if(v.x[_so_ir] _op_ v.x[_so_l]){\
_swap(type,v.x[_so_l],v.x[_so_ir]);\
_swap(typeu,u.x[_so_l],u.x[_so_ir]);\
}\
if(v.x[_so_ir] _op_ v.x[_so_l+1]){\
_swap(type,v.x[_so_l+1],v.x[_so_ir]);\
_swap(typeu,u.x[_so_l+1],u.x[_so_ir]);\
}\
if(v.x[_so_l+1] _op_ v.x[_so_l]){\
_swap(type,v.x[_so_l],v.x[_so_l+1]);\
_swap(typeu,u.x[_so_l],u.x[_so_l+1]);\
}\
_so_i = _so_l+1,_so_j = _so_ir;\
_so_a = v.x[_so_l+1];\
_so_b = u.x[_so_l+1];\
for(;;){\
do ++_so_i; while(v.x[_so_i] _op_ _so_a);\
do --_so_j; while(_so_a _op_ v.x[_so_j]);\
if(_so_j<_so_i) break;\
_swap(type,v.x[_so_i],v.x[_so_j]);\
_swap(typeu,u.x[_so_i],u.x[_so_j]);\
}\
v.x[_so_l+1] = v.x[_so_j];\
v.x[_so_j] = _so_a;\
u.x[_so_l+1] = u.x[_so_j];\
u.x[_so_j] = _so_b;\
_so_jstack += 2;\
if(_so_ir-_so_i+1>=_so_j-_so_l){\
_so_istack[_so_jstack] = _so_ir;\
_so_istack[_so_jstack-1] = _so_i;\
_so_ir = _so_j-1;\
}else{\
_so_istack[_so_jstack] = _so_j-1;\
_so_istack[_so_jstack-1] = _so_l;\
_so_l = _so_i;\
}\
}\
}\
}while(0)
#define vec_sortc(type,v,cmpr)\
do{\
int _so_i,_so_ir = v.vsize-1,_so_j,_so_k,_so_l = 0,_so_istack[50],_so_jstack = -1;\
type _so_a;\
for(;;){\
if(_so_ir-_so_l<7){\
for(_so_j = _so_l+1;_so_j<=_so_ir;++_so_j){\
_so_a = v.x[_so_j];\
for(_so_i = _so_j-1;_so_i>=_so_l;--_so_i){\
if(cmpr(&_so_a,&(v.x[_so_i]))>0) break;\
v.x[_so_i+1] = v.x[_so_i];\
}\
v.x[_so_i+1] = _so_a;\
}\
if(_so_jstack==-1) break;\
_so_ir = _so_istack[_so_jstack];\
_so_l = _so_istack[_so_jstack-1];\
_so_jstack -= 2;\
}else{\
_so_k = (_so_l+_so_ir)>>1;\
_swap(type,v.x[_so_k],v.x[_so_l+1]);\
if(cmpr(&(v.x[_so_ir]),&(v.x[_so_l]))<=0) _swap(type,v.x[_so_l],v.x[_so_ir]);\
if(cmpr(&(v.x[_so_ir]),&(v.x[_so_l+1]))<=0) _swap(type,v.x[_so_l+1],v.x[_so_ir]);\
if(cmpr(&(v.x[_so_l+1]),&(v.x[_so_l]))<=0) _swap(type,v.x[_so_l],v.x[_so_l+1]);\
_so_i = _so_l+1,_so_j = _so_ir;\
_so_a = v.x[_so_l+1];\
for(;;){\
do ++_so_i; while(cmpr(&(v.x[_so_i]),&_so_a)<=0);\
do --_so_j; while(cmpr(&_so_a,&(v.x[_so_j]))<=0);\
if(_so_j<_so_i) break;\
_swap(type,v.x[_so_i],v.x[_so_j]);\
}\
v.x[_so_l+1] = v.x[_so_j];\
v.x[_so_j] = _so_a;\
_so_jstack += 2;\
if(_so_ir-_so_i+1>=_so_j-_so_l){\
_so_istack[_so_jstack] = _so_ir;\
_so_istack[_so_jstack-1] = _so_i;\
_so_ir = _so_j-1;\
}else{\
_so_istack[_so_jstack] = _so_j-1;\
_so_istack[_so_jstack-1] = _so_l;\
_so_l = _so_i;\
}\
}\
}\
}while(0)
#define vec_sortpc(type,v,typeu,u,cmpr)\
do{\
int _so_i,_so_ir = v.vsize-1,_so_j,_so_k,_so_l = 0,_so_istack[50],_so_jstack = -1;\
type _so_a;\
typeu _so_b;\
for(;;){\
if(_so_ir-_so_l<7){\
for(_so_j = _so_l+1;_so_j<=_so_ir;++_so_j){\
_so_a = v.x[_so_j];\
_so_b = u.x[_so_j];\
for(_so_i = _so_j-1;_so_i>=_so_l;--_so_i){\
if(cmpr(&_so_a,&(v.x[_so_i]))>0) break;\
v.x[_so_i+1] = v.x[_so_i];\
u.x[_so_i+1] = u.x[_so_i];\
}\
v.x[_so_i+1] = _so_a;\
u.x[_so_i+1] = _so_b;\
}\
if(_so_jstack==-1) break;\
_so_ir = _so_istack[_so_jstack];\
_so_l = _so_istack[_so_jstack-1];\
_so_jstack -= 2;\
}else{\
_so_k = (_so_l+_so_ir)>>1;\
_swap(type,v.x[_so_k],v.x[_so_l+1]);\
_swap(typeu,u.x[_so_k],u.x[_so_l+1]);\
if(cmpr(&(v.x[_so_ir]),&(v.x[_so_l]))<=0){\
_swap(type,v.x[_so_l],v.x[_so_ir]);\
_swap(typeu,u.x[_so_l],u.x[_so_ir]);\
}\
if(cmpr(&(v.x[_so_ir]),&(v.x[_so_l+1]))<=0){\
_swap(type,v.x[_so_l+1],v.x[_so_ir]);\
_swap(typeu,u.x[_so_l+1],u.x[_so_ir]);\
}\
if(cmpr(&(v.x[_so_l+1]),&(v.x[_so_l]))<=0){\
_swap(type,v.x[_so_l],v.x[_so_l+1]);\
_swap(typeu,u.x[_so_l],u.x[_so_l+1]);\
}\
_so_i = _so_l+1,_so_j = _so_ir;\
_so_a = v.x[_so_l+1];\
_so_b = u.x[_so_l+1];\
for(;;){\
do ++_so_i; while(cmpr(&(v.x[_so_i]),&_so_a)<=0);\
do --_so_j; while(cmpr(&_so_a,&(v.x[_so_j]))<=0);\
if(_so_j<_so_i) break;\
_swap(type,v.x[_so_i],v.x[_so_j]);\
_swap(typeu,u.x[_so_i],u.x[_so_j]);\
}\
v.x[_so_l+1] = v.x[_so_j];\
v.x[_so_j] = _so_a;\
u.x[_so_l+1] = u.x[_so_j];\
u.x[_so_j] = _so_b;\
_so_jstack += 2;\
if(_so_ir-_so_i+1>=_so_j-_so_l){\
_so_istack[_so_jstack] = _so_ir;\
_so_istack[_so_jstack-1] = _so_i;\
_so_ir = _so_j-1;\
}else{\
_so_istack[_so_jstack] = _so_j-1;\
_so_istack[_so_jstack-1] = _so_l;\
_so_l = _so_i;\
}\
}\
}\
}while(0)
#define vec_swap(type,des,src)\
do{\
_swap(int,des.vsize,src.vsize);\
_swap(int,des.asize,src.asize);\
_swap(type *,des.x,src.x);\
}while(0)
#define vec2_swap(type,des,src)\
do{\
_swap(int,des.vsize,src.vsize);\
_swap(int,des.asize,src.asize);\
_swap(VEC_##type *,des.x,src.x);\
}while(0)
#define _vec_top(v) (v.x[v.vsize-1])
#define vec_top(type,v) _vec_top(v)
#define _vec2_top(v) _vec_top(v)
#define vec2_top(type,v) _vec2_top(v)
#endif