Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
58d0db34
Commit
58d0db34
authored
9 years ago
by
Joshua Colp
Committed by
Gerrit Code Review
9 years ago
Browse files
Options
Downloads
Plain Diff
Merge "vector: Add REMOVE, ADD_SORTED and RESET macros"
parents
9bb9d225
87d8b367
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/asterisk/vector.h
+73
-17
73 additions, 17 deletions
include/asterisk/vector.h
tests/test_vector.c
+28
-3
28 additions, 3 deletions
tests/test_vector.c
with
101 additions
and
20 deletions
include/asterisk/vector.h
+
73
−
17
View file @
58d0db34
...
@@ -272,6 +272,36 @@
...
@@ -272,6 +272,36 @@
res; \
res; \
})
})
/*!
* \brief Add an element into a sorted vector
*
* \param vec Sorted vector to add to.
* \param elem Element to insert.
* \param cmp A strcmp compatible compare function.
*
* \return 0 on success.
* \return Non-zero on failure.
*
* \warning Use of this macro on an unsorted vector will produce unpredictable results
*/
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp) ({ \
int res = 0; \
size_t __idx = (vec)->current; \
do { \
if (__make_room((vec)->current, vec) != 0) { \
res = -1; \
break; \
} \
while (__idx > 0 && (cmp((vec)->elems[__idx - 1], elem) > 0)) { \
(vec)->elems[__idx] = (vec)->elems[__idx - 1]; \
__idx--; \
} \
(vec)->elems[__idx] = elem; \
(vec)->current++; \
} while (0); \
res; \
})
/*!
/*!
* \brief Remove an element from a vector by index.
* \brief Remove an element from a vector by index.
*
*
...
@@ -280,17 +310,39 @@
...
@@ -280,17 +310,39 @@
*
*
* \param vec Vector to remove from.
* \param vec Vector to remove from.
* \param idx Index of the element to remove.
* \param idx Index of the element to remove.
* \param preserve_order Preserve the vector order.
*
* \return The element that was removed.
* \return The element that was removed.
*/
*/
#define AST_VECTOR_REMOVE_UNORDERED(vec, idx) ({ \
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered) ({ \
typeof((vec)->elems[0]) res; \
typeof((vec)->elems[0]) res; \
size_t __idx = (idx); \
size_t __idx = (idx); \
ast_assert(__idx < (vec)->current); \
ast_assert(__idx < (vec)->current); \
res = (vec)->elems[__idx]; \
res = (vec)->elems[__idx]; \
(vec)->elems[__idx] = (vec)->elems[--(vec)->current]; \
if ((preserve_ordered)) { \
size_t __move; \
__move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \
memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \
(vec)->current--; \
} else { \
(vec)->elems[__idx] = (vec)->elems[--(vec)->current]; \
}; \
res; \
res; \
})
})
/*!
* \brief Remove an element from an unordered vector by index.
*
* Note that elements in the vector may be reordered, so that the remove can
* happen in constant time.
*
* \param vec Vector to remove from.
* \param idx Index of the element to remove.
* \return The element that was removed.
*/
#define AST_VECTOR_REMOVE_UNORDERED(vec, idx) \
AST_VECTOR_REMOVE(vec, idx, 0)
/*!
/*!
* \brief Remove an element from a vector by index while maintaining order.
* \brief Remove an element from a vector by index while maintaining order.
*
*
...
@@ -298,17 +350,8 @@
...
@@ -298,17 +350,8 @@
* \param idx Index of the element to remove.
* \param idx Index of the element to remove.
* \return The element that was removed.
* \return The element that was removed.
*/
*/
#define AST_VECTOR_REMOVE_ORDERED(vec, idx) ({ \
#define AST_VECTOR_REMOVE_ORDERED(vec, idx) \
typeof((vec)->elems[0]) res; \
AST_VECTOR_REMOVE(vec, idx, 1)
size_t __idx = (idx); \
size_t __move; \
ast_assert(__idx < (vec)->current); \
res = (vec)->elems[__idx]; \
__move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \
memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \
(vec)->current--; \
res; \
})
/*!
/*!
* \brief Remove an element from a vector that matches the given comparison
* \brief Remove an element from a vector that matches the given comparison
...
@@ -420,6 +463,17 @@
...
@@ -420,6 +463,17 @@
*/
*/
#define AST_VECTOR_SIZE(vec) (vec)->current
#define AST_VECTOR_SIZE(vec) (vec)->current
/*!
* \brief Reset vector.
*
* \param vec Vector to reset.
* \param callback A cleanup callback or AST_VECTOR_ELEM_CLEANUP_NOOP.
*/
#define AST_VECTOR_RESET(vec, cleanup) ({ \
AST_VECTOR_CALLBACK_VOID(vec, cleanup); \
(vec)->current = 0; \
})
/*!
/*!
* \brief Get an address of element in a vector.
* \brief Get an address of element in a vector.
*
*
...
@@ -508,6 +562,8 @@
...
@@ -508,6 +562,8 @@
* \brief Execute a callback on every element in a vector returning the matching
* \brief Execute a callback on every element in a vector returning the matching
* elements in a new vector
* elements in a new vector
*
*
* This macro basically provides a filtered clone.
*
* \param vec Vector to operate on.
* \param vec Vector to operate on.
* \param callback A callback that takes at least 1 argument (the element)
* \param callback A callback that takes at least 1 argument (the element)
* plus number of optional arguments
* plus number of optional arguments
...
...
This diff is collapsed.
Click to expand it.
tests/test_vector.c
+
28
−
3
View file @
58d0db34
...
@@ -63,7 +63,9 @@ AST_TEST_DEFINE(basic_ops)
...
@@ -63,7 +63,9 @@ AST_TEST_DEFINE(basic_ops)
char
*
CCC
=
"CCC"
;
char
*
CCC
=
"CCC"
;
char
*
YYY
=
"YYY"
;
char
*
YYY
=
"YYY"
;
char
*
ZZZ
=
"ZZZ"
;
char
*
ZZZ
=
"ZZZ"
;
char
CCC2
[
4
];
strcpy
(
CCC2
,
"CCC"
);
switch
(
cmd
)
{
switch
(
cmd
)
{
case
TEST_INIT
:
case
TEST_INIT
:
info
->
name
=
"basic"
;
info
->
name
=
"basic"
;
...
@@ -202,6 +204,29 @@ AST_TEST_DEFINE(basic_ops)
...
@@ -202,6 +204,29 @@ AST_TEST_DEFINE(basic_ops)
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
0
)
==
CCC
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
0
)
==
CCC
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
cleanup_count
==
1
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
cleanup_count
==
1
,
rc
,
cleanup
);
/* Test INSERT_SORTED */
AST_VECTOR_FREE
(
&
sv1
);
ast_test_validate
(
test
,
AST_VECTOR_INIT
(
&
sv1
,
0
)
==
0
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_ADD_SORTED
(
&
sv1
,
BBB
,
strcmp
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_ADD_SORTED
(
&
sv1
,
ZZZ
,
strcmp
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_ADD_SORTED
(
&
sv1
,
CCC
,
strcmp
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_ADD_SORTED
(
&
sv1
,
AAA
,
strcmp
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_ADD_SORTED
(
&
sv1
,
CCC2
,
strcmp
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
0
)
==
AAA
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
1
)
==
BBB
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
2
)
==
CCC
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
3
)
==
CCC2
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_GET
(
&
sv1
,
4
)
==
ZZZ
,
rc
,
cleanup
);
cleanup_count
=
0
;
AST_VECTOR_RESET
(
&
sv1
,
cleanup
);
ast_test_validate_cleanup
(
test
,
AST_VECTOR_SIZE
(
&
sv1
)
==
0
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
sv1
.
max
>=
5
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
sv1
.
elems
!=
NULL
,
rc
,
cleanup
);
ast_test_validate_cleanup
(
test
,
cleanup_count
==
5
,
rc
,
cleanup
);
cleanup:
cleanup:
AST_VECTOR_FREE
(
&
sv1
);
AST_VECTOR_FREE
(
&
sv1
);
return
rc
;
return
rc
;
...
@@ -218,13 +243,13 @@ AST_TEST_DEFINE(basic_ops_integer)
...
@@ -218,13 +243,13 @@ AST_TEST_DEFINE(basic_ops_integer)
int
rc
=
AST_TEST_PASS
;
int
rc
=
AST_TEST_PASS
;
int
AAA
=
1
;
int
AAA
=
1
;
int
BBB
=
2
;
int
BBB
=
3
;
int
CCC
=
3
;
int
CCC
=
5
;
int
ZZZ
=
26
;
int
ZZZ
=
26
;
switch
(
cmd
)
{
switch
(
cmd
)
{
case
TEST_INIT
:
case
TEST_INIT
:
info
->
name
=
"basic
integer"
;
info
->
name
=
"basic
_
integer"
;
info
->
category
=
"/main/vector/"
;
info
->
category
=
"/main/vector/"
;
info
->
summary
=
"Test integer vector basic ops"
;
info
->
summary
=
"Test integer vector basic ops"
;
info
->
description
=
"Test integer vector basic ops"
;
info
->
description
=
"Test integer vector basic ops"
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment