Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Harfbuzz
提交
538da749
T
Third Party Harfbuzz
项目概览
OpenHarmony
/
Third Party Harfbuzz
1 年多 前同步成功
通知
0
Star
18
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Harfbuzz
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
538da749
编写于
10月 29, 2017
作者:
B
Behdad Esfahbod
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add hb-sort-r, a portable qsort_r() replacement
上级
923a8f52
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
228 addition
and
0 deletion
+228
-0
src/Makefile.sources
src/Makefile.sources
+1
-0
src/hb-sort-r.hh
src/hb-sort-r.hh
+227
-0
未找到文件。
src/Makefile.sources
浏览文件 @
538da749
...
...
@@ -40,6 +40,7 @@ HB_BASE_sources = \
hb-shaper-impl-private.hh
\
hb-shaper-private.hh
\
hb-shaper.cc
\
hb-sort-r.hh
\
hb-string-array.hh
\
hb-unicode-private.hh
\
hb-unicode.cc
\
...
...
src/hb-sort-r.hh
0 → 100644
浏览文件 @
538da749
/* Isaac Turner 29 April 2014 Public Domain */
#ifndef HB_SORT_R_HH
#define HB_SORT_R_HH
#include <hb-private.hh>
/* From https://github.com/noporpoise/sort_r */
/*
hb_sort_r function to be exported.
Parameters:
base is the array to be sorted
nel is the number of elements in the array
width is the size in bytes of each element of the array
compar is the comparison function
arg is a pointer to be passed to the comparison function
void hb_sort_r(void *base, size_t nel, size_t width,
int (*compar)(const void *_a, const void *_b, void *_arg),
void *arg);
*/
#define _SORT_R_INLINE inline
#if (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \
defined __FreeBSD__ || defined __DragonFly__)
# define _SORT_R_BSD
#elif (defined _GNU_SOURCE || defined __gnu_hurd__ || defined __GNU__ || \
defined __linux__ || defined __MINGW32__ || defined __GLIBC__)
# define _SORT_R_LINUX
#elif (defined _WIN32 || defined _WIN64 || defined __WINDOWS__)
# define _SORT_R_WINDOWS
# undef _SORT_R_INLINE
# define _SORT_R_INLINE __inline
#else
/* Using our own recursive quicksort sort_r_simple() */
#endif
#if (defined NESTED_QSORT && NESTED_QSORT == 0)
# undef NESTED_QSORT
#endif
/* swap a, b iff a>b */
/* __restrict is same as restrict but better support on old machines */
static
_SORT_R_INLINE
int
sort_r_cmpswap
(
char
*
__restrict
a
,
char
*
__restrict
b
,
size_t
w
,
int
(
*
compar
)(
const
void
*
_a
,
const
void
*
_b
,
void
*
_arg
),
void
*
arg
)
{
char
tmp
,
*
end
=
a
+
w
;
if
(
compar
(
a
,
b
,
arg
)
>
0
)
{
for
(;
a
<
end
;
a
++
,
b
++
)
{
tmp
=
*
a
;
*
a
=
*
b
;
*
b
=
tmp
;
}
return
1
;
}
return
0
;
}
/* Implement recursive quicksort ourselves */
/* Note: quicksort is not stable, equivalent values may be swapped */
static
_SORT_R_INLINE
void
sort_r_simple
(
void
*
base
,
size_t
nel
,
size_t
w
,
int
(
*
compar
)(
const
void
*
_a
,
const
void
*
_b
,
void
*
_arg
),
void
*
arg
)
{
char
*
b
=
(
char
*
)
base
,
*
end
=
b
+
nel
*
w
;
if
(
nel
<
7
)
{
/* Insertion sort for arbitrarily small inputs */
char
*
pi
,
*
pj
;
for
(
pi
=
b
+
w
;
pi
<
end
;
pi
+=
w
)
{
for
(
pj
=
pi
;
pj
>
b
&&
sort_r_cmpswap
(
pj
-
w
,
pj
,
w
,
compar
,
arg
);
pj
-=
w
)
{}
}
}
else
{
/* nel > 6; Quicksort */
/* Use median of first, middle and last items as pivot */
char
*
x
,
*
y
,
*
xend
,
ch
;
char
*
pl
,
*
pr
;
char
*
last
=
b
+
w
*
(
nel
-
1
),
*
tmp
;
char
*
l
[
3
];
l
[
0
]
=
b
;
l
[
1
]
=
b
+
w
*
(
nel
/
2
);
l
[
2
]
=
last
;
if
(
compar
(
l
[
0
],
l
[
1
],
arg
)
>
0
)
{
tmp
=
l
[
0
];
l
[
0
]
=
l
[
1
];
l
[
1
]
=
tmp
;
}
if
(
compar
(
l
[
1
],
l
[
2
],
arg
)
>
0
)
{
tmp
=
l
[
1
];
l
[
1
]
=
l
[
2
];
l
[
2
]
=
tmp
;
/* swap(l[1],l[2]) */
if
(
compar
(
l
[
0
],
l
[
1
],
arg
)
>
0
)
{
tmp
=
l
[
0
];
l
[
0
]
=
l
[
1
];
l
[
1
]
=
tmp
;
}
}
/* swap l[id], l[2] to put pivot as last element */
for
(
x
=
l
[
1
],
y
=
last
,
xend
=
x
+
w
;
x
<
xend
;
x
++
,
y
++
)
{
ch
=
*
x
;
*
x
=
*
y
;
*
y
=
ch
;
}
pl
=
b
;
pr
=
last
;
while
(
pl
<
pr
)
{
for
(;
pl
<
pr
;
pl
+=
w
)
{
if
(
sort_r_cmpswap
(
pl
,
pr
,
w
,
compar
,
arg
))
{
pr
-=
w
;
/* pivot now at pl */
break
;
}
}
for
(;
pl
<
pr
;
pr
-=
w
)
{
if
(
sort_r_cmpswap
(
pl
,
pr
,
w
,
compar
,
arg
))
{
pl
+=
w
;
/* pivot now at pr */
break
;
}
}
}
sort_r_simple
(
b
,
(
pl
-
b
)
/
w
,
w
,
compar
,
arg
);
sort_r_simple
(
pl
+
w
,
(
end
-
(
pl
+
w
))
/
w
,
w
,
compar
,
arg
);
}
}
#if defined NESTED_QSORT
static
_SORT_R_INLINE
void
hb_sort_r
(
void
*
base
,
size_t
nel
,
size_t
width
,
int
(
*
compar
)(
const
void
*
_a
,
const
void
*
_b
,
void
*
aarg
),
void
*
arg
)
{
int
nested_cmp
(
const
void
*
a
,
const
void
*
b
)
{
return
compar
(
a
,
b
,
arg
);
}
qsort
(
base
,
nel
,
width
,
nested_cmp
);
}
#else
/* !NESTED_QSORT */
/* Declare structs and functions */
#if defined _SORT_R_BSD
/* Ensure qsort_r is defined */
extern
void
qsort_r
(
void
*
base
,
size_t
nel
,
size_t
width
,
void
*
thunk
,
int
(
*
compar
)(
void
*
_thunk
,
const
void
*
_a
,
const
void
*
_b
));
#endif
#if defined _SORT_R_BSD || defined _SORT_R_WINDOWS
/* BSD (qsort_r), Windows (qsort_s) require argument swap */
struct
sort_r_data
{
void
*
arg
;
int
(
*
compar
)(
const
void
*
_a
,
const
void
*
_b
,
void
*
_arg
);
};
static
_SORT_R_INLINE
int
sort_r_arg_swap
(
void
*
s
,
const
void
*
a
,
const
void
*
b
)
{
struct
sort_r_data
*
ss
=
(
struct
sort_r_data
*
)
s
;
return
(
ss
->
compar
)(
a
,
b
,
ss
->
arg
);
}
#endif
#if defined _SORT_R_LINUX
#if 0 /* BE: To avoid redeclaration warning. */
typedef int(* __compar_d_fn_t)(const void *, const void *, void *);
extern void qsort_r(void *base, size_t nel, size_t width,
__compar_d_fn_t __compar, void *arg)
__attribute__((nonnull (1, 4)));
#endif
#endif
/* implementation */
static
_SORT_R_INLINE
void
hb_sort_r
(
void
*
base
,
size_t
nel
,
size_t
width
,
int
(
*
compar
)(
const
void
*
_a
,
const
void
*
_b
,
void
*
_arg
),
void
*
arg
)
{
#if defined _SORT_R_LINUX
#if defined __GLIBC__ && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8))
/* no qsort_r in glibc before 2.8, need to use nested qsort */
sort_r_simple
(
base
,
nel
,
width
,
compar
,
arg
);
#else
qsort_r
(
base
,
nel
,
width
,
compar
,
arg
);
#endif
#elif defined _SORT_R_BSD
struct
sort_r_data
tmp
;
tmp
.
arg
=
arg
;
tmp
.
compar
=
compar
;
qsort_r
(
base
,
nel
,
width
,
&
tmp
,
sort_r_arg_swap
);
#elif defined _SORT_R_WINDOWS
struct
sort_r_data
tmp
;
tmp
.
arg
=
arg
;
tmp
.
compar
=
compar
;
qsort_s
(
base
,
nel
,
width
,
sort_r_arg_swap
,
&
tmp
);
#else
/* Fall back to our own quicksort implementation */
sort_r_simple
(
base
,
nel
,
width
,
compar
,
arg
);
#endif
}
#endif
/* !NESTED_QSORT */
#undef _SORT_R_INLINE
#undef _SORT_R_WINDOWS
#undef _SORT_R_LINUX
#undef _SORT_R_BSD
#endif
/* HB_SORT_R_HH */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录