OCT 1. 更新vector
This commit is contained in:
parent
445a82aa8f
commit
6c2e5c464d
|
@ -11,10 +11,6 @@
|
||||||
#ifndef SRC_ZVECTOR_H_
|
#ifndef SRC_ZVECTOR_H_
|
||||||
#define SRC_ZVECTOR_H_
|
#define SRC_ZVECTOR_H_
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,8 +23,11 @@ extern "C" {
|
||||||
// so we know on which platform and which features
|
// so we know on which platform and which features
|
||||||
// we can use:
|
// we can use:
|
||||||
#include "zvector_checks.h"
|
#include "zvector_checks.h"
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
// Include c_vector configuration header
|
// Include vector configuration header
|
||||||
#include "zvector_config.h"
|
#include "zvector_config.h"
|
||||||
|
|
||||||
// Declare required structs:
|
// Declare required structs:
|
||||||
|
@ -39,25 +38,28 @@ typedef struct p_vector *c_vector;
|
||||||
/*
|
/*
|
||||||
* Vector Properties Flags can be used to tell ZVector
|
* Vector Properties Flags can be used to tell ZVector
|
||||||
* which types of properties we want to enable for each
|
* which types of properties we want to enable for each
|
||||||
* given c_vector we are creating.
|
* given vector we are creating.
|
||||||
* Each c_vector can have multiple properties enabled at the
|
* Each vector can have multiple properties enabled at the
|
||||||
* same time, you can use the typical C form to specify multiple
|
* same time, you can use the typical C form to specify multiple
|
||||||
* properties for the same c_vector:
|
* properties for the same vector:
|
||||||
*
|
*
|
||||||
* ZV_SEC_WIPE | ZV_BYREF
|
* ZV_SEC_WIPE | ZV_BYREF
|
||||||
*
|
*
|
||||||
* The above will create a c_vector that supports passing items to
|
* The above will create a vector that supports passing items to
|
||||||
* it by reference (instead of copying them into the c_vector) and
|
* it by reference (instead of copying them into the vector) and
|
||||||
* having Secure Wipe enabled, so that when an element is deleted
|
* having Secure Wipe enabled, so that when an element is deleted
|
||||||
* its reference will also be fully zeroed out before freeing it.
|
* its reference will also be fully zeroed out before freeing it.
|
||||||
*/
|
*/
|
||||||
enum ZVECT_PROPERTIES {
|
enum ZVECT_PROPERTIES {
|
||||||
ZV_NONE = 0, // Sets or Resets all c_vector's properties to 0.
|
ZV_NONE = 0, // Sets or Resets all vector's properties to 0.
|
||||||
ZV_SEC_WIPE = 1 << 0, // Sets the c_vector for automatic Secure Wipe of items.
|
ZV_SEC_WIPE = 1 << 0, // Sets the vector for automatic Secure Wipe of items.
|
||||||
ZV_BYREF = 1 << 1, // Sets the c_vector to store items by reference instead of copying them as per default.
|
ZV_BYREF = 1 << 1, // Sets the vector to store items by reference instead of
|
||||||
ZV_CIRCULAR = 1
|
// copying them as per default.
|
||||||
<< 2, // Sets the c_vector to be a circular c_vector (so it will not grow in capacity automatically). Elements will be overwritten as in typical circular buffers!
|
ZV_CIRCULAR = 1 << 2, // Sets the vector to be a circular vector (so it will
|
||||||
ZV_NOLOCKING = 1 << 3, // This Property means the c_vector will not use mutexes, be careful using it!
|
// not grow in capacity automatically). Elements will be
|
||||||
|
// overwritten as in typical circular buffers!
|
||||||
|
ZV_NOLOCKING = 1 << 3, // This Property means the vector will not use mutexes,
|
||||||
|
// be careful using it!
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ZVECT_ERR {
|
enum ZVECT_ERR {
|
||||||
|
@ -72,6 +74,8 @@ enum ZVECT_ERR {
|
||||||
ZVERR_OPNOTALLOWED = -9
|
ZVERR_OPNOTALLOWED = -9
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern unsigned int LOG_PRIORITY;
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
** Public API declaration: **
|
** Public API declaration: **
|
||||||
*****************************/
|
*****************************/
|
||||||
|
@ -79,7 +83,7 @@ enum ZVECT_ERR {
|
||||||
// Vector construction/Destruction and memory control:
|
// Vector construction/Destruction and memory control:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_create creates and returns a new c_vector
|
* vect_create creates and returns a new vector
|
||||||
* of the specified "capacity", with a storage area that
|
* of the specified "capacity", with a storage area that
|
||||||
* can store items of "item_size" size and, if we want to
|
* can store items of "item_size" size and, if we want to
|
||||||
* have an automatic secure erasing enabled (ZV_SEC_WIPE
|
* have an automatic secure erasing enabled (ZV_SEC_WIPE
|
||||||
|
@ -90,16 +94,16 @@ enum ZVECT_ERR {
|
||||||
c_vector vect_create(zvect_index capacity, size_t item_size, uint32_t properties);
|
c_vector vect_create(zvect_index capacity, size_t item_size, uint32_t properties);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_destroy destroys the specified c_vector and, if
|
* vect_destroy destroys the specified vector and, if
|
||||||
* secure_wipe is enabled, also ensure erasing each single
|
* secure_wipe is enabled, also ensure erasing each single
|
||||||
* value in the c_vector before destroying it.
|
* value in the vector before destroying it.
|
||||||
*/
|
*/
|
||||||
void vect_destroy(c_vector);
|
void vect_destroy(c_vector);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_shrink is useful when operating on systems with
|
* vect_shrink is useful when operating on systems with
|
||||||
* small amount of RAM, and it basically allows to shrink
|
* small amount of RAM, and it basically allows to shrink
|
||||||
* the c_vector capacity to match the actual used size, to
|
* the vector capacity to match the actual used size, to
|
||||||
* save unused memory locations.
|
* save unused memory locations.
|
||||||
*/
|
*/
|
||||||
void vect_shrink(c_vector const v);
|
void vect_shrink(c_vector const v);
|
||||||
|
@ -107,7 +111,7 @@ void vect_shrink(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_set_wipefunct allows you to pass ZVector a pointer to a custom
|
* vect_set_wipefunct allows you to pass ZVector a pointer to a custom
|
||||||
* function (of your creation) to securely wipe data from the c_vector v
|
* function (of your creation) to securely wipe data from the vector v
|
||||||
* when automatic safe wipe is called.
|
* when automatic safe wipe is called.
|
||||||
*/
|
*/
|
||||||
void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t size));
|
void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t size));
|
||||||
|
@ -115,29 +119,43 @@ void vect_set_wipefunct(c_vector const v, void (*f1)(const void *item, size_t si
|
||||||
// Vector state checks:
|
// Vector state checks:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_is_empty returns true if the c_vector is empty
|
* vect_is_empty returns true if the vector is empty
|
||||||
* and false if the c_vector is NOT empty.
|
* and false if the vector is NOT empty.
|
||||||
*/
|
*/
|
||||||
bool vect_is_empty(c_vector const v);
|
int vect_is_empty(struct p_vector *const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_size returns the actual size (the number of)
|
* vect_size returns the actual size (the number of)
|
||||||
* USED slots in the c_vector storage.
|
* USED slots in the vector storage.
|
||||||
*/
|
*/
|
||||||
zvect_index vect_size(c_vector const v);
|
zvect_index vect_size(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_clear clears out a c_vector and also resizes it
|
* vect_size returns the maximum size (the max number of)
|
||||||
|
* slots in the vector storage.
|
||||||
|
*/
|
||||||
|
zvect_index vect_max_size(c_vector const v);
|
||||||
|
|
||||||
|
void *vect_begin(c_vector const v);
|
||||||
|
void *vect_end(c_vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vect_clear clears out a vector and also resizes it
|
||||||
* to its initial capacity.
|
* to its initial capacity.
|
||||||
*/
|
*/
|
||||||
void vect_clear(c_vector const v);
|
void vect_clear(c_vector const v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vector status bits control
|
||||||
|
*/
|
||||||
bool vect_check_status(const c_vector v, zvect_index flag_id);
|
bool vect_check_status(const c_vector v, zvect_index flag_id);
|
||||||
|
|
||||||
bool vect_set_status(const c_vector v, zvect_index flag_id);
|
bool vect_set_status(const c_vector v, zvect_index flag_id);
|
||||||
|
|
||||||
bool vect_clear_status(const c_vector v, zvect_index flag_id);
|
bool vect_clear_status(const c_vector v, zvect_index flag_id);
|
||||||
|
|
||||||
|
bool vect_toggle_status(const c_vector v, zvect_index flag_id);
|
||||||
|
|
||||||
#if (ZVECT_THREAD_SAFE == 1)
|
#if (ZVECT_THREAD_SAFE == 1)
|
||||||
// Vector Thread Safe functions:
|
// Vector Thread Safe functions:
|
||||||
|
|
||||||
|
@ -164,34 +182,34 @@ void vect_lock_enable(void);
|
||||||
void vect_lock_disable(void);
|
void vect_lock_disable(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_lock allows you to lock the given c_vector to
|
* vect_lock allows you to lock the given vector to
|
||||||
* have exclusive write access from your own thread.
|
* have exclusive write access from your own thread.
|
||||||
* When you lock a c_vector directly then ZVector will
|
* When you lock a vector directly then ZVector will
|
||||||
* NOT use its internal locking mechanism for that
|
* NOT use its internal locking mechanism for that
|
||||||
* specific c_vector.
|
* specific vector.
|
||||||
*
|
*
|
||||||
* Example of use: To lock a c_vector called v
|
* Example of use: To lock a vector called v
|
||||||
* vect_lock(v);
|
* vect_lock(v);
|
||||||
*/
|
*/
|
||||||
zvect_retval vect_lock(c_vector const v);
|
zvect_retval vect_lock(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_trylock will try to lock the given c_vector to
|
* vect_trylock will try to lock the given vector to
|
||||||
* have exclusive write access from your own thread.
|
* have exclusive write access from your own thread.
|
||||||
* When you lock a c_vector directly then ZVector will
|
* When you lock a vector directly then ZVector will
|
||||||
* NOT use its internal locking mechanism for that
|
* NOT use its internal locking mechanism for that
|
||||||
* specific c_vector.
|
* specific vector.
|
||||||
*
|
*
|
||||||
* Example of use: To lock a c_vector called v
|
* Example of use: To lock a vector called v
|
||||||
* vect_trylock(v);
|
* vect_trylock(v);
|
||||||
*/
|
*/
|
||||||
zvect_retval vect_trylock(c_vector const v);
|
zvect_retval vect_trylock(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_lock allows you to unlock the given c_vector that
|
* vect_lock allows you to unlock the given vector that
|
||||||
* you have previously locked with vect_lock.
|
* you have previously locked with vect_lock.
|
||||||
*
|
*
|
||||||
* Example of use: To unlock a c_vector called v
|
* Example of use: To unlock a vector called v
|
||||||
* vect_unlock(v);
|
* vect_unlock(v);
|
||||||
*/
|
*/
|
||||||
zvect_retval vect_unlock(c_vector const v);
|
zvect_retval vect_unlock(c_vector const v);
|
||||||
|
@ -223,11 +241,11 @@ zvect_retval vect_sem_post(const c_vector v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_push and vect_pop are used to use the
|
* vect_push and vect_pop are used to use the
|
||||||
* c_vector as a dynamic stack.
|
* vector as a dynamic stack.
|
||||||
*
|
*
|
||||||
* int i = 3;
|
* int i = 3;
|
||||||
* vect_push(v, &i) pushes the element 3 at the
|
* vect_push(v, &i) pushes the element 3 at the
|
||||||
* back of the c_vector v, which
|
* back of the vector v, which
|
||||||
* corresponds to the top of a
|
* corresponds to the top of a
|
||||||
* Stack.
|
* Stack.
|
||||||
*/
|
*/
|
||||||
|
@ -235,25 +253,25 @@ void vect_push(c_vector const v, const void *item);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_pop(v) "pops" (returns) the element
|
* vect_pop(v) "pops" (returns) the element
|
||||||
* at the back of the c_vector as
|
* at the back of the vector as
|
||||||
* a regular pop would do with
|
* a regular pop would do with
|
||||||
* an element at the top of a
|
* an element at the top of a
|
||||||
* stack. Remember when you use
|
* stack. Remember when you use
|
||||||
* vect_pop the element you
|
* vect_pop the element you
|
||||||
* receive is also removed from
|
* receive is also removed from
|
||||||
* the c_vector!
|
* the vector!
|
||||||
*/
|
*/
|
||||||
void *vect_pop(c_vector const v);
|
void *vect_pop(c_vector const v);
|
||||||
#define vect_pop_back(x) vect_pop(x)
|
#define vect_pop_back(x) vect_pop(x)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_add adds a new item into the c_vector and,
|
* vect_add adds a new item into the vector and,
|
||||||
* if required, will also reorganize the c_vector.
|
* if required, will also reorganize the vector.
|
||||||
*
|
*
|
||||||
* int i = 3;
|
* int i = 3;
|
||||||
* vect_add(v, &i) will add the new item 3 in
|
* vect_add(v, &i) will add the new item 3 in
|
||||||
* the c_vector v at the end
|
* the vector v at the end
|
||||||
* (or back) of the c_vector v.
|
* (or back) of the vector v.
|
||||||
*/
|
*/
|
||||||
void vect_add(c_vector const v, const void *item);
|
void vect_add(c_vector const v, const void *item);
|
||||||
#define vect_push_back(x, y) vect_add(x, y)
|
#define vect_push_back(x, y) vect_add(x, y)
|
||||||
|
@ -261,7 +279,7 @@ void vect_add(c_vector const v, const void *item);
|
||||||
/*
|
/*
|
||||||
* int i = 4;
|
* int i = 4;
|
||||||
* vect_add_at(v, &i, 2) will add the new item 4 at
|
* vect_add_at(v, &i, 2) will add the new item 4 at
|
||||||
* position 2 in the c_vector v
|
* position 2 in the vector v
|
||||||
* and move all the elements
|
* and move all the elements
|
||||||
* from the original 2nd onward
|
* from the original 2nd onward
|
||||||
* of a position to make space
|
* of a position to make space
|
||||||
|
@ -272,22 +290,22 @@ void vect_add_at(c_vector const v, const void *item, zvect_index index);
|
||||||
/*
|
/*
|
||||||
* int i = 5;
|
* int i = 5;
|
||||||
* vect_add_front(v, &i) will add the new item 5 at
|
* vect_add_front(v, &i) will add the new item 5 at
|
||||||
* the beginning of the c_vector
|
* the beginning of the vector
|
||||||
* v (or front) and will also
|
* v (or front) and will also
|
||||||
* move all the existing
|
* move all the existing
|
||||||
* elements of one position in
|
* elements of one position in
|
||||||
* the c_vector to make space for
|
* the vector to make space for
|
||||||
* the new item 5 at the front
|
* the new item 5 at the front
|
||||||
* of c_vector v.
|
* of vector v.
|
||||||
*/
|
*/
|
||||||
void vect_add_front(c_vector const v, const void *item);
|
void vect_add_front(c_vector const v, const void *item);
|
||||||
#define vect_push_front(x, y) vect_add_front(x, y)
|
#define vect_push_front(x, y) vect_add_front(x, y)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_get returns an item from the specified c_vector
|
* vect_get returns an item from the specified vector
|
||||||
*
|
*
|
||||||
* vect_get(v) will return the ast element in
|
* vect_get(v) will return the ast element in
|
||||||
* the v c_vector (but will not remove
|
* the v vector (but will not remove
|
||||||
* the element as it happens in
|
* the element as it happens in
|
||||||
* vect_pop(v)).
|
* vect_pop(v)).
|
||||||
*/
|
*/
|
||||||
|
@ -297,25 +315,25 @@ void *vect_get(c_vector const v);
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* vect_get_at(v, 3) will return the element at location
|
* vect_get_at(v, 3) will return the element at location
|
||||||
* 3 in the c_vector v.
|
* 3 in the vector v.
|
||||||
*/
|
*/
|
||||||
void *vect_get_at(c_vector const v, const zvect_index i);
|
void *vect_get_at(c_vector const v, const zvect_index i);
|
||||||
#define vect_at(v, x) vect_get_at(v, x)
|
#define vect_at(v, x) vect_get_at(v, x)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_get_front(v) will return the first element in
|
* vect_get_front(v) will return the first element in
|
||||||
* the c_vector v.
|
* the vector v.
|
||||||
*/
|
*/
|
||||||
void *vect_get_front(c_vector const v);
|
void *vect_get_front(c_vector const v);
|
||||||
#define vect_front(v) vect_get_front(v)
|
#define vect_front(v) vect_get_front(v)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*vect_put allows you to REPLACE an item
|
*vect_put allows you to REPLACE an item
|
||||||
* in the c_vector.
|
* in the vector.
|
||||||
*
|
*
|
||||||
* int i = 3;
|
* int i = 3;
|
||||||
* vect_put(v, &i) will replace the last element
|
* vect_put(v, &i) will replace the last element
|
||||||
* in the c_vector with 3.
|
* in the vector with 3.
|
||||||
*/
|
*/
|
||||||
void vect_put(c_vector const v, const void *item);
|
void vect_put(c_vector const v, const void *item);
|
||||||
|
|
||||||
|
@ -323,7 +341,7 @@ void vect_put(c_vector const v, const void *item);
|
||||||
*
|
*
|
||||||
* int i = 4;
|
* int i = 4;
|
||||||
* vect_put_at(v, &i, 2) will replace the 3rd element
|
* vect_put_at(v, &i, 2) will replace the 3rd element
|
||||||
* (2 + 1, as c_vector's 1st item
|
* (2 + 1, as vector's 1st item
|
||||||
* starts at v[0]) with the
|
* starts at v[0]) with the
|
||||||
* item 4.
|
* item 4.
|
||||||
*/
|
*/
|
||||||
|
@ -333,54 +351,54 @@ void vect_put_at(c_vector const v, const void *item, const zvect_index i);
|
||||||
*
|
*
|
||||||
* int i = 5;
|
* int i = 5;
|
||||||
* vect_put_front(v, &i) will replace the 1st element
|
* vect_put_front(v, &i) will replace the 1st element
|
||||||
* of the c_vector with the item
|
* of the vector with the item
|
||||||
* 5.
|
* 5.
|
||||||
*/
|
*/
|
||||||
void vect_put_front(c_vector const v, const void *item);
|
void vect_put_front(c_vector const v, const void *item);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_remove removes an item from the c_vector
|
* vect_remove removes an item from the vector
|
||||||
* and reorganise the c_vector. It also returns
|
* and reorganise the vector. It also returns
|
||||||
* the item remove from the c_vector, so you can
|
* the item remove from the vector, so you can
|
||||||
* use it to simulate a stack behaviour as well.
|
* use it to simulate a stack behaviour as well.
|
||||||
*
|
*
|
||||||
* vect_remove(v) will remove and return the
|
* vect_remove(v) will remove and return the
|
||||||
* last item in the c_vector.
|
* last item in the vector.
|
||||||
*/
|
*/
|
||||||
void *vect_remove(c_vector const v);
|
void *vect_remove(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_remove_at(v, 3) will remove the 3rd item in
|
* vect_remove_at(v, 3) will remove the 3rd item in
|
||||||
* the c_vector and return it.
|
* the vector and return it.
|
||||||
*/
|
*/
|
||||||
void *vect_remove_at(c_vector const v, const zvect_index i);
|
void *vect_remove_at(c_vector const v, const zvect_index i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_remove_front(v) will remove the 1st item in
|
* vect_remove_front(v) will remove the 1st item in
|
||||||
* the c_vector and return it.
|
* the vector and return it.
|
||||||
*/
|
*/
|
||||||
void *vect_remove_front(c_vector const v);
|
void *vect_remove_front(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_delete deletes an item from the c_vector
|
* vect_delete deletes an item from the vector
|
||||||
* and reorganise the c_vector. It does not return
|
* and reorganise the vector. It does not return
|
||||||
* the item like remove.
|
* the item like remove.
|
||||||
*
|
*
|
||||||
* vect_delete(v) will delete and the last
|
* vect_delete(v) will delete and the last
|
||||||
* item in the c_vector.
|
* item in the vector.
|
||||||
*/
|
*/
|
||||||
void vect_delete(c_vector const v);
|
void vect_delete(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_delete_at(v, 3) will delete the 3rd item in
|
* vect_delete_at(v, 3) will delete the 3rd item in
|
||||||
* the c_vector.
|
* the vector.
|
||||||
*/
|
*/
|
||||||
void vect_delete_at(c_vector const v, const zvect_index i);
|
void vect_delete_at(c_vector const v, const zvect_index i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_delete_range(v, 20, 30)
|
* vect_delete_range(v, 20, 30)
|
||||||
* will delete items from item
|
* will delete items from item
|
||||||
* 20 to item 30 in the c_vector
|
* 20 to item 30 in the vector
|
||||||
* v.
|
* v.
|
||||||
*/
|
*/
|
||||||
void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element);
|
void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element);
|
||||||
|
@ -388,7 +406,7 @@ void vect_delete_range(c_vector const v, const zvect_index first_element, const
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* vect_delete_front(v) will delete the 1st item in
|
* vect_delete_front(v) will delete the 1st item in
|
||||||
* the c_vector.
|
* the vector.
|
||||||
*/
|
*/
|
||||||
void vect_delete_front(c_vector const v);
|
void vect_delete_front(c_vector const v);
|
||||||
|
|
||||||
|
@ -401,11 +419,11 @@ void vect_delete_front(c_vector const v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_swap is a function that allows you to swap two
|
* vect_swap is a function that allows you to swap two
|
||||||
* items in the same c_vector.
|
* items in the same vector.
|
||||||
* You just pass the c_vector and the index of both the
|
* You just pass the vector and the index of both the
|
||||||
* two items to swap.
|
* two items to swap.
|
||||||
*
|
*
|
||||||
* For example to swap item 3 with item 22 on c_vector v
|
* For example to swap item 3 with item 22 on vector v
|
||||||
* use:
|
* use:
|
||||||
* vect_swap(v, 3, 22);
|
* vect_swap(v, 3, 22);
|
||||||
*/
|
*/
|
||||||
|
@ -413,23 +431,23 @@ void vect_swap(c_vector const v, const zvect_index s, const zvect_index e);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_swap_range is a function that allows to swap
|
* vect_swap_range is a function that allows to swap
|
||||||
* a range of items in the same c_vector.
|
* a range of items in the same vector.
|
||||||
* You just pass the c_vector, the index of the first item
|
* You just pass the vector, the index of the first item
|
||||||
* to swap, the index of the last item to swap and the
|
* to swap, the index of the last item to swap and the
|
||||||
* index of the first item to swap with.
|
* index of the first item to swap with.
|
||||||
*
|
*
|
||||||
* For example to swap items from 10 to 20 with items
|
* For example to swap items from 10 to 20 with items
|
||||||
* from 30 to 40 on c_vector v, use:
|
* from 30 to 40 on vector v, use:
|
||||||
* vect_swap_range(v, 10, 20, 30);
|
* vect_swap_range(v, 10, 20, 30);
|
||||||
*/
|
*/
|
||||||
void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2);
|
void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_rotate_left is a function that allows to rotate
|
* vect_rotate_left is a function that allows to rotate
|
||||||
* a c_vector of "i" positions to the left (or from the
|
* a vector of "i" positions to the left (or from the
|
||||||
* "front" to the "end").
|
* "front" to the "end").
|
||||||
*
|
*
|
||||||
* For example to rotate a c_vector called v of 5 positions
|
* For example to rotate a vector called v of 5 positions
|
||||||
* to the left, use:
|
* to the left, use:
|
||||||
* vect_rotate_left(v, 5);
|
* vect_rotate_left(v, 5);
|
||||||
*/
|
*/
|
||||||
|
@ -437,34 +455,34 @@ void vect_rotate_left(c_vector const v, const zvect_index i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_rotate_right is a function that allows to rotate
|
* vect_rotate_right is a function that allows to rotate
|
||||||
* a c_vector of "i" positions to the right (or from the
|
* a vector of "i" positions to the right (or from the
|
||||||
* "end" to the "front").
|
* "end" to the "front").
|
||||||
*
|
*
|
||||||
* For example to rotate a c_vector called v of 5 positions
|
* For example to rotate a vector called v of 5 positions
|
||||||
* to the right, use:
|
* to the right, use:
|
||||||
* vect_rotate_right(v, 5);
|
* vect_rotate_right(v, 5);
|
||||||
*/
|
*/
|
||||||
void vect_rotate_right(c_vector const v, const zvect_index i);
|
void vect_rotate_right(c_vector const v, const zvect_index i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_qsort allows you to sort a given c_vector.
|
* vect_qsort allows you to sort a given vector.
|
||||||
* The algorithm used to sort a c_vector is Quicksort with
|
* The algorithm used to sort a vector is Quicksort with
|
||||||
* 3 ways partitioning which is generally much faster than
|
* 3 ways partitioning which is generally much faster than
|
||||||
* traditional quicksort.
|
* traditional quicksort.
|
||||||
*
|
*
|
||||||
* To sort a c_vector you need to provide a custom function
|
* To sort a vector you need to provide a custom function
|
||||||
* that allows vect_sort to determine the order and which
|
* that allows vect_sort to determine the order and which
|
||||||
* elements of a c_vector are used to order it in the way
|
* elements of a vector are used to order it in the way
|
||||||
* you desire. It pretty much works as a regular C qsort
|
* you desire. It pretty much works as a regular C qsort
|
||||||
* function. It quite fast given that it only reorders
|
* function. It quite fast given that it only reorders
|
||||||
* pointers to your datastructures stored in the c_vector.
|
* pointers to your datastructures stored in the vector.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *));
|
void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_bsearch is a function that allows to perform
|
* vect_bsearch is a function that allows to perform
|
||||||
* a binary search over the c_vector we pass to it to
|
* a binary search over the vector we pass to it to
|
||||||
* find the item "key" using the comparison function
|
* find the item "key" using the comparison function
|
||||||
* "f1".
|
* "f1".
|
||||||
*
|
*
|
||||||
|
@ -474,31 +492,26 @@ void vect_qsort(c_vector const v, int (*compare_func)(const void *, const void *
|
||||||
* some improvements over the original one (look at the
|
* some improvements over the original one (look at the
|
||||||
* sources for more details).
|
* sources for more details).
|
||||||
*
|
*
|
||||||
* For example to search for the number 5 in a c_vector
|
* For example to search for the number 5 in a vector
|
||||||
* called v using a compare function called "my_compare"
|
* called v using a compare function called "my_compare"
|
||||||
* use:
|
* use:
|
||||||
* int i = 5;
|
* int i = 5;
|
||||||
* vect_bsearch(v, &i, my_compare);
|
* vect_bsearch(v, &i, my_compare);
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index);
|
bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index);
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* vect_add_ordered allows the insertion of new items in
|
* vect_add_ordered allows the insertion of new items in
|
||||||
* an ordered fashion. Please note that for this to work
|
* an ordered fashion. Please note that for this to work
|
||||||
* fine you should always use only ordered vectors or if
|
* fine you should always use only ordered vectors or if
|
||||||
* an empty c_vector use vect_add_ordered only to add new
|
* an empty vector use vect_add_ordered only to add new
|
||||||
* values to it!
|
* values to it!
|
||||||
*
|
*
|
||||||
* As for any other ordered function you must provide
|
* As for any other ordered function you must provide
|
||||||
* your own compare function (syntax is the usual one,
|
* your own compare function (syntax is the usual one,
|
||||||
* and it's the same as for regular CLib qsort function)
|
* and it's the same as for regular CLib qsort function)
|
||||||
*
|
*
|
||||||
* To add item 3 to a c_vector called v using vect_add_ordered
|
* To add item 3 to a vector called v using vect_add_ordered
|
||||||
* (assuming your compare function is called my_compare),
|
* (assuming your compare function is called my_compare),
|
||||||
* use:
|
* use:
|
||||||
*
|
*
|
||||||
|
@ -513,23 +526,23 @@ void vect_add_ordered(c_vector const v, const void *value, int (*f1)(const void
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_apply allows you to apply a C function to
|
* vect_apply allows you to apply a C function to
|
||||||
* each item in the c_vector, so you just pass the c_vector,
|
* each item in the vector, so you just pass the vector,
|
||||||
* the function you want to execute against each item on
|
* the function you want to execute against each item on
|
||||||
* a c_vector and make sure such function is declared and
|
* a vector and make sure such function is declared and
|
||||||
* defined to accept a "void *" pointer which will be the
|
* defined to accept a "void *" pointer which will be the
|
||||||
* pointer to the single item in the c_vector passed to your
|
* pointer to the single item in the vector passed to your
|
||||||
* function. The function has no return value because it's
|
* function. The function has no return value because it's
|
||||||
* not necessary if you receive the pointer to the item.
|
* not necessary if you receive the pointer to the item.
|
||||||
* You can simply update the content of the memory pointed
|
* You can simply update the content of the memory pointed
|
||||||
* by the item passed and that is much faster than having
|
* by the item passed and that is much faster than having
|
||||||
* to deal with return values especially when you'll be
|
* to deal with return values especially when you'll be
|
||||||
* using complex data structures as item of the c_vector.
|
* using complex data structures as item of the vector.
|
||||||
*/
|
*/
|
||||||
void vect_apply(c_vector const v, void (*f1)(void *));
|
void vect_apply(c_vector const v, void (*f1)(void *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_apply_if is a function that will apply "f1" C function
|
* vect_apply_if is a function that will apply "f1" C function
|
||||||
* to each and every item in c_vector v1, IF the return value of
|
* to each and every item in vector v1, IF the return value of
|
||||||
* function f2 is true. So it allows what is known as conditional
|
* function f2 is true. So it allows what is known as conditional
|
||||||
* application. f2 will receive an item from v1 as first parameter
|
* application. f2 will receive an item from v1 as first parameter
|
||||||
* and an item from v2 (at the same position of the item in v1) as
|
* and an item from v2 (at the same position of the item in v1) as
|
||||||
|
@ -557,20 +570,22 @@ void vect_apply(c_vector const v, void (*f1)(void *));
|
||||||
*/
|
*/
|
||||||
void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *));
|
void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *));
|
||||||
|
|
||||||
|
void vect_apply_range(c_vector const v, void (*f)(void *), const zvect_index x, const zvect_index y);
|
||||||
|
|
||||||
// Operations with multiple vectors:
|
// Operations with multiple vectors:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_copy is a function that allows to copy a specified
|
* vect_copy is a function that allows to copy a specified
|
||||||
* set of elements from a c_vector to another.
|
* set of elements from a vector to another.
|
||||||
* Please note: only vectors with the same data size (the
|
* Please note: only vectors with the same data size (the
|
||||||
* parameter we pass during the creation of both vectors)
|
* parameter we pass during the creation of both vectors)
|
||||||
* can be copied into the other!
|
* can be copied into the other!
|
||||||
*
|
*
|
||||||
* vect_copy(v1, v2, 3, 5) will copy all the items in
|
* vect_copy(v1, v2, 3, 5) will copy all the items in
|
||||||
* c_vector v2, from the 4th item
|
* vector v2, from the 4th item
|
||||||
* till the 9th (3 + 5, remember
|
* till the 9th (3 + 5, remember
|
||||||
* c_vector items start from 0) in
|
* vector items start from 0) in
|
||||||
* the c_vector v1. So at the end
|
* the vector v1. So at the end
|
||||||
* of the process you'll have such
|
* of the process you'll have such
|
||||||
* items copied at the end of v1.
|
* items copied at the end of v1.
|
||||||
*/
|
*/
|
||||||
|
@ -578,17 +593,17 @@ void vect_copy(c_vector const v1, c_vector const v2, zvect_index start, zvect_in
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_insert is a function that allows to copy a specified
|
* vect_insert is a function that allows to copy a specified
|
||||||
* set of elements from a c_vector to another and "insert"
|
* set of elements from a vector to another and "insert"
|
||||||
* them from a specified position in the destination c_vector.
|
* them from a specified position in the destination vector.
|
||||||
* Please note: only vectors with the same data size (the
|
* Please note: only vectors with the same data size (the
|
||||||
* parameter we pass during the creation of both vectors)
|
* parameter we pass during the creation of both vectors)
|
||||||
* can be copied into the other!
|
* can be copied into the other!
|
||||||
*
|
*
|
||||||
* vect_insert(v1, v2, 3, 5, 7) will copy all the items in
|
* vect_insert(v1, v2, 3, 5, 7) will copy all the items in
|
||||||
* c_vector v2, from the 4th item
|
* vector v2, from the 4th item
|
||||||
* till the 9th (3 + 5, remember
|
* till the 9th (3 + 5, remember
|
||||||
* c_vector items start from 0) in
|
* vector items start from 0) in
|
||||||
* the c_vector v1 from position 7.
|
* the vector v1 from position 7.
|
||||||
* So at the end of the process
|
* So at the end of the process
|
||||||
* you'll have such items "inserted"
|
* you'll have such items "inserted"
|
||||||
* inside v1.
|
* inside v1.
|
||||||
|
@ -601,9 +616,9 @@ void vect_insert(c_vector const v1,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_move is a function that allows to move a specified
|
* vect_move is a function that allows to move a specified
|
||||||
* set of items from one c_vector to another.
|
* set of items from one vector to another.
|
||||||
* It will also re-organise the source c_vector and (obviously)
|
* It will also re-organise the source vector and (obviously)
|
||||||
* expand the destination c_vector if needed.
|
* expand the destination vector if needed.
|
||||||
* Please note: only vectors of the same data size can be moved
|
* Please note: only vectors of the same data size can be moved
|
||||||
* one into the other!
|
* one into the other!
|
||||||
*
|
*
|
||||||
|
@ -615,11 +630,11 @@ void vect_move(c_vector const v1, c_vector const v2, zvect_index start, zvect_in
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vect_move_if is a function that allows to move a specified
|
* vect_move_if is a function that allows to move a specified
|
||||||
* set of items from one c_vector to another if the condition
|
* set of items from one vector to another if the condition
|
||||||
* returned by the function pointed by f2 function pointer
|
* returned by the function pointed by f2 function pointer
|
||||||
* is true.
|
* is true.
|
||||||
* It will also re-organise the source c_vector and (obviously)
|
* It will also re-organise the source vector and (obviously)
|
||||||
* expand the destination c_vector if needed.
|
* expand the destination vector if needed.
|
||||||
* Please note: only vectors of the same data size can be moved
|
* Please note: only vectors of the same data size can be moved
|
||||||
* one into the other!
|
* one into the other!
|
||||||
*
|
*
|
||||||
|
@ -637,9 +652,9 @@ zvect_retval vect_move_if(c_vector const v1,
|
||||||
/*
|
/*
|
||||||
* vect_merge is a function that merges together 2 vectors of
|
* vect_merge is a function that merges together 2 vectors of
|
||||||
* the same data size. At the end of the process, the source
|
* the same data size. At the end of the process, the source
|
||||||
* c_vector will be destroyed.
|
* vector will be destroyed.
|
||||||
*
|
*
|
||||||
* vect_merge(v1, v2) will merge c_vector v2 to v1 and then
|
* vect_merge(v1, v2) will merge vector v2 to v1 and then
|
||||||
* destroy v2. So at the end of the job
|
* destroy v2. So at the end of the job
|
||||||
* v1 will contain the old v1 items +
|
* v1 will contain the old v1 items +
|
||||||
* all v2 items.
|
* all v2 items.
|
||||||
|
|
|
@ -17,18 +17,20 @@
|
||||||
/*
|
/*
|
||||||
* Few code standard notes:
|
* Few code standard notes:
|
||||||
*
|
*
|
||||||
* p_ <- indicate a PRIVATE method or variable. Not reachable outside this module.
|
* p_ <- indicate a PRIVATE method or variable. Not reachable outside this
|
||||||
|
* module.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Include standard C libs headers
|
/* Include standard C libs headers */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Include vector.h header
|
/* Include vector.h header */
|
||||||
#include "zvector/zvector.h"
|
#include "zvector/zvector.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#if (OS_TYPE == 1)
|
#if (OS_TYPE == 1)
|
||||||
#if (!defined(macOS))
|
#if (!defined(macOS))
|
||||||
|
@ -105,16 +107,19 @@ enum {
|
||||||
// Useful macros
|
// Useful macros
|
||||||
// # define min(x, y) (((x) < (y)) ? (x) : (y))
|
// # define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
#ifndef UNUSED
|
||||||
#define UNUSED(x) (void)x
|
#define UNUSED(x) (void)x
|
||||||
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
// Define the vector data structure:
|
/* Define the vector data structure:
|
||||||
|
*
|
||||||
// This is ZVector core data structure, it is the structure of a ZVector vector :)
|
* This is ZVector core data structure, it is the structure of a ZVector
|
||||||
// Please note: fields order is based on "most used fields" to help a bit with cache
|
* vector :)
|
||||||
|
* Please note: fields order is based on "most used fields" to help a bit
|
||||||
|
* with cache
|
||||||
|
*/
|
||||||
struct ZVECT_PACKING p_vector {
|
struct ZVECT_PACKING p_vector {
|
||||||
zvect_index cap_left; // - Max capacity allocated on the
|
zvect_index cap_left; // - Max capacity allocated on the
|
||||||
// left.
|
// left.
|
||||||
|
@ -189,6 +194,9 @@ struct ZVECT_PACKING p_vector {
|
||||||
#endif // ZVECT_THREAD_SAFE
|
#endif // ZVECT_THREAD_SAFE
|
||||||
} ZVECT_DATAALIGN;
|
} ZVECT_DATAALIGN;
|
||||||
|
|
||||||
|
// Internal representation of a vector
|
||||||
|
typedef struct p_vector *const ivector;
|
||||||
|
|
||||||
// Initialisation state:
|
// Initialisation state:
|
||||||
static uint32_t p_init_state = 0;
|
static uint32_t p_init_state = 0;
|
||||||
|
|
||||||
|
@ -219,8 +227,12 @@ unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM | ZVLP_LOW | Z
|
||||||
unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM);
|
unsigned int LOG_PRIORITY = (ZVLP_ERROR | ZVLP_HIGH | ZVLP_MEDIUM);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Local declaration of private functions
|
||||||
|
void p_init_zvect(void);
|
||||||
|
zvect_retval p_vect_clear(ivector v);
|
||||||
|
|
||||||
// This is a vprintf wrapper nothing special:
|
// This is a vprintf wrapper nothing special:
|
||||||
static void LOG_MOD(int const priority, const char *const format, ...) {
|
static void log_msg(int const priority, const char *const format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
|
@ -262,9 +274,9 @@ static void *safe_strncpy(const char *const str_src, size_t max_len) {
|
||||||
|
|
||||||
str_dst = (void *)malloc(sizeof(char *) * (sizeof(tmp_dst) + 1));
|
str_dst = (void *)malloc(sizeof(char *) * (sizeof(tmp_dst) + 1));
|
||||||
if (str_dst == NULL) {
|
if (str_dst == NULL) {
|
||||||
LOG_MOD(ZVLP_ERROR, "Error: %*i, %s\n", 8, -1000, "Out of memory!");
|
log_msg(ZVLP_ERROR, "Error: %*i, %s\n", 8, -1000, "Out of memory!");
|
||||||
} else {
|
} else {
|
||||||
strncpy((char *)str_dst, tmp_dst, sizeof(char) * max_len);
|
strncpy((char *)str_dst, tmp_dst, max_len);
|
||||||
}
|
}
|
||||||
return str_dst;
|
return str_dst;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +288,7 @@ static void
|
||||||
p_throw_error(const zvect_retval error_code, const char *error_message) {
|
p_throw_error(const zvect_retval error_code, const char *error_message) {
|
||||||
int32_t locally_allocated = 0;
|
int32_t locally_allocated = 0;
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
unsigned long msg_len = 0;
|
size_t msg_len = 0;
|
||||||
|
|
||||||
if (error_message == NULL) {
|
if (error_message == NULL) {
|
||||||
msg_len = sizeof(char *) * 255;
|
msg_len = sizeof(char *) * 255;
|
||||||
|
@ -288,13 +300,13 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
|
||||||
if (locally_allocated) {
|
if (locally_allocated) {
|
||||||
switch (error_code) {
|
switch (error_code) {
|
||||||
case ZVERR_VECTUNDEF:
|
case ZVERR_VECTUNDEF:
|
||||||
message = (char *)safe_strncpy("Undefined or uninitialized c_vector.\n\0", msg_len);
|
message = (char *)safe_strncpy("Undefined or uninitialized vector.\n\0", msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_IDXOUTOFBOUND:
|
case ZVERR_IDXOUTOFBOUND:
|
||||||
message = (char *)safe_strncpy("Index out of bound.\n\0", msg_len);
|
message = (char *)safe_strncpy("Index out of bound.\n\0", msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_OUTOFMEM:
|
case ZVERR_OUTOFMEM:
|
||||||
message = (char *)safe_strncpy("Not enough memory to allocate space for the c_vector.\n\0", msg_len);
|
message = (char *)safe_strncpy("Not enough memory to allocate space for the vector.\n\0", msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_VECTCORRUPTED:
|
case ZVERR_VECTCORRUPTED:
|
||||||
message = (char *)safe_strncpy("Vector corrupted.\n\0", msg_len);
|
message = (char *)safe_strncpy("Vector corrupted.\n\0", msg_len);
|
||||||
|
@ -303,11 +315,12 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
|
||||||
message = (char *)safe_strncpy("Race condition detected, cannot continue.\n\0", msg_len);
|
message = (char *)safe_strncpy("Race condition detected, cannot continue.\n\0", msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_VECTTOOSMALL:
|
case ZVERR_VECTTOOSMALL:
|
||||||
message = (char *)safe_strncpy("Destination c_vector is smaller than source.\n\0", msg_len);
|
message = (char *)safe_strncpy("Destination vector is smaller than source.\n\0", msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_VECTDATASIZE:
|
case ZVERR_VECTDATASIZE:
|
||||||
message = (char *)safe_strncpy(
|
message = (char *)safe_strncpy(
|
||||||
"This operation requires two (or more vectors) with the same data size.\n\0",
|
"This operation requires two (or more "
|
||||||
|
"vectors) with the same data size.\n\0",
|
||||||
msg_len);
|
msg_len);
|
||||||
break;
|
break;
|
||||||
case ZVERR_VECTEMPTY:
|
case ZVERR_VECTEMPTY:
|
||||||
|
@ -324,7 +337,7 @@ p_throw_error(const zvect_retval error_code, const char *error_message) {
|
||||||
message = (char *)safe_strncpy(error_message, msg_len);
|
message = (char *)safe_strncpy(error_message, msg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_MOD(ZVLP_ERROR, "Error: %*i, %s\n", 8, error_code, message);
|
log_msg(ZVLP_ERROR, "Error: %*i, %s\n", 8, error_code, message);
|
||||||
if (locally_allocated) {
|
if (locally_allocated) {
|
||||||
free((void *)message);
|
free((void *)message);
|
||||||
}
|
}
|
||||||
|
@ -374,9 +387,9 @@ static inline
|
||||||
ZVECT_ALWAYSINLINE
|
ZVECT_ALWAYSINLINE
|
||||||
static inline void *p_vect_memmove(const void *__restrict dst, const void *__restrict src, size_t size) {
|
static inline void *p_vect_memmove(const void *__restrict dst, const void *__restrict src, size_t size) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_memmove: dst %*p\n", 14, dst);
|
log_msg(ZVLP_INFO, "p_vect_memmove: dst %*p\n", 14, dst);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_memmove: src %*p\n", 14, src);
|
log_msg(ZVLP_INFO, "p_vect_memmove: src %*p\n", 14, src);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_memmove: size %*u\n", 14, size);
|
log_msg(ZVLP_INFO, "p_vect_memmove: size %*u\n", 14, size);
|
||||||
#endif
|
#endif
|
||||||
return memmove((void *)dst, src, size);
|
return memmove((void *)dst, src, size);
|
||||||
}
|
}
|
||||||
|
@ -437,10 +450,14 @@ static inline void mutex_destroy(pthread_mutex_t *lock) {
|
||||||
|
|
||||||
static inline int semaphore_init
|
static inline int semaphore_init
|
||||||
#if !defined(macOS)
|
#if !defined(macOS)
|
||||||
(sem_t *sem, int value) {
|
(sem_t *sem, int value)
|
||||||
|
#else
|
||||||
|
(dispatch_semaphore_t *sem, int value)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if !defined(macOS)
|
||||||
return sem_init(sem, 0, value);
|
return sem_init(sem, 0, value);
|
||||||
#else
|
#else
|
||||||
(dispatch_semaphore_t *sem, int value) {
|
|
||||||
*sem = dispatch_semaphore_create(value);
|
*sem = dispatch_semaphore_create(value);
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -448,10 +465,14 @@ static inline int semaphore_init
|
||||||
|
|
||||||
static inline int semaphore_destroy
|
static inline int semaphore_destroy
|
||||||
#if !defined(macOS)
|
#if !defined(macOS)
|
||||||
(sem_t *sem) {
|
(sem_t *sem)
|
||||||
|
#else
|
||||||
|
(dispatch_semaphore_t *sem)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if !defined(macOS)
|
||||||
return sem_destroy(sem);
|
return sem_destroy(sem);
|
||||||
#else
|
#else
|
||||||
(dispatch_semaphore_t *sem) {
|
|
||||||
return 0; // dispatch_semaphore_destroy(sem);
|
return 0; // dispatch_semaphore_destroy(sem);
|
||||||
(void)sem;
|
(void)sem;
|
||||||
#endif
|
#endif
|
||||||
|
@ -526,8 +547,8 @@ static inline zvect_retval lock_after_signal(const c_vector v, const int32_t loc
|
||||||
/*
|
/*
|
||||||
* TODO: Write a generic function to allow user to use signals:
|
* TODO: Write a generic function to allow user to use signals:
|
||||||
|
|
||||||
static inline zvect_retval wait_for_signal(const vector v, const int32_t lock_type, bool (*f1)(const vector v), ) {
|
static inline zvect_retval wait_for_signal(const c_vector v, const int32_t
|
||||||
if (lock_type >= v->lock_type) {
|
lock_type, bool (*f1)(const c_vector v), ) { if (lock_type >= v->lock_type) {
|
||||||
//if (!mutex_trylock(&(v->lock))) {
|
//if (!mutex_trylock(&(v->lock))) {
|
||||||
while(!(*f1)(v)) {
|
while(!(*f1)(v)) {
|
||||||
// wait until we get a signal
|
// wait until we get a signal
|
||||||
|
@ -598,7 +619,7 @@ static inline zvect_index p_vect_size(const c_vector v) {
|
||||||
return (v->end > v->begin) ? (v->end - v->begin) : (v->begin - v->end);
|
return (v->end > v->begin) ? (v->end - v->begin) : (v->begin - v->end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void p_item_safewipe(c_vector const v, void *const item) {
|
static inline void p_item_safewipe(ivector v, void *const item) {
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
if (!(v->status & ZVS_CUST_WIPE_ON)) {
|
if (!(v->status & ZVS_CUST_WIPE_ON)) {
|
||||||
memset(item, 0, v->data_size);
|
memset(item, 0, v->data_size);
|
||||||
|
@ -627,7 +648,7 @@ bool vect_set_status(const c_vector v, zvect_index flag_id) {
|
||||||
zvect_retval rval = p_usr_status(flag_id);
|
zvect_retval rval = p_usr_status(flag_id);
|
||||||
|
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
v->status |= 1UL << flag_id;
|
v->status |= 1 << flag_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool)rval;
|
return (bool)rval;
|
||||||
|
@ -637,7 +658,7 @@ bool vect_clear_status(const c_vector v, zvect_index flag_id) {
|
||||||
zvect_retval rval = p_usr_status(flag_id);
|
zvect_retval rval = p_usr_status(flag_id);
|
||||||
|
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
v->status &= ~(1UL << flag_id);
|
v->status &= ~(1 << flag_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool)rval;
|
return (bool)rval;
|
||||||
|
@ -647,13 +668,13 @@ bool vect_toggle_status(const c_vector v, zvect_index flag_id) {
|
||||||
zvect_retval rval = p_usr_status(flag_id);
|
zvect_retval rval = p_usr_status(flag_id);
|
||||||
|
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
v->status ^= (1UL << flag_id);
|
v->status ^= (1 << flag_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void p_free_items(c_vector const v, zvect_index first, zvect_index offset) {
|
static void p_free_items(ivector v, zvect_index first, zvect_index offset) {
|
||||||
if (p_vect_size(v) == 0) {
|
if (p_vect_size(v) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -685,9 +706,7 @@ static void p_free_items(c_vector const v, zvect_index first, zvect_index offset
|
||||||
/*
|
/*
|
||||||
* Set vector capacity to a specific new_capacity value
|
* Set vector capacity to a specific new_capacity value
|
||||||
*/
|
*/
|
||||||
static zvect_retval p_vect_set_capacity(c_vector const v,
|
static zvect_retval p_vect_set_capacity(ivector v, const zvect_index direction, const zvect_index new_capacity_) {
|
||||||
const zvect_index direction,
|
|
||||||
const zvect_index new_capacity_) {
|
|
||||||
zvect_index new_capacity = new_capacity_;
|
zvect_index new_capacity = new_capacity_;
|
||||||
|
|
||||||
if (new_capacity <= v->init_capacity) {
|
if (new_capacity <= v->init_capacity) {
|
||||||
|
@ -741,7 +760,7 @@ static zvect_retval p_vect_set_capacity(c_vector const v,
|
||||||
/*
|
/*
|
||||||
* This function increase the CAPACITY of a vector.
|
* This function increase the CAPACITY of a vector.
|
||||||
*/
|
*/
|
||||||
static zvect_retval p_vect_increase_capacity(c_vector const v, const zvect_index direction) {
|
static zvect_retval p_vect_increase_capacity(ivector v, const zvect_index direction) {
|
||||||
zvect_index new_capacity;
|
zvect_index new_capacity;
|
||||||
|
|
||||||
if (!direction) {
|
if (!direction) {
|
||||||
|
@ -774,7 +793,7 @@ static zvect_retval p_vect_increase_capacity(c_vector const v, const zvect_index
|
||||||
/*
|
/*
|
||||||
* This function decrease the CAPACITY of a vector.
|
* This function decrease the CAPACITY of a vector.
|
||||||
*/
|
*/
|
||||||
static zvect_retval p_vect_decrease_capacity(c_vector const v, const zvect_index direction) {
|
static zvect_retval p_vect_decrease_capacity(ivector v, const zvect_index direction) {
|
||||||
// Check if new capacity is smaller than initial capacity
|
// Check if new capacity is smaller than initial capacity
|
||||||
if (p_vect_capacity(v) <= v->init_capacity) {
|
if (p_vect_capacity(v) <= v->init_capacity) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -849,7 +868,7 @@ static zvect_retval p_vect_decrease_capacity(c_vector const v, const zvect_index
|
||||||
* not its size. To reduce the size of a vector we
|
* not its size. To reduce the size of a vector we
|
||||||
* need to remove items from it.
|
* need to remove items from it.
|
||||||
*/
|
*/
|
||||||
static zvect_retval p_vect_shrink(c_vector const v) {
|
static zvect_retval p_vect_shrink(ivector v) {
|
||||||
if (v->init_capacity < 2) {
|
if (v->init_capacity < 2) {
|
||||||
v->init_capacity = 2;
|
v->init_capacity = 2;
|
||||||
}
|
}
|
||||||
|
@ -867,8 +886,8 @@ static zvect_retval p_vect_shrink(c_vector const v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// shrink the vector:
|
// shrink the vector:
|
||||||
// Given that zvector supports vectors that can grow on the left and on the right
|
// Given that zvector supports vectors that can grow on the left and on the
|
||||||
// I cannot use realloc here.
|
// right I cannot use realloc here.
|
||||||
void **new_data = (void **)malloc(sizeof(void *) * new_capacity);
|
void **new_data = (void **)malloc(sizeof(void *) * new_capacity);
|
||||||
if (new_data == NULL) {
|
if (new_data == NULL) {
|
||||||
return ZVERR_OUTOFMEM;
|
return ZVERR_OUTOFMEM;
|
||||||
|
@ -900,7 +919,7 @@ static zvect_retval p_vect_shrink(c_vector const v) {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
// Creation and destruction primitives:
|
// Creation and destruction primitives:
|
||||||
|
|
||||||
zvect_retval p_vect_clear(c_vector const v) {
|
zvect_retval p_vect_clear(ivector v) {
|
||||||
// Clear the vector:
|
// Clear the vector:
|
||||||
if (!vect_is_empty(v)) {
|
if (!vect_is_empty(v)) {
|
||||||
p_free_items(v, 0, (p_vect_size(v) - 1));
|
p_free_items(v, 0, (p_vect_size(v) - 1));
|
||||||
|
@ -910,7 +929,8 @@ zvect_retval p_vect_clear(c_vector const v) {
|
||||||
v->begin = v->end = 0;
|
v->begin = v->end = 0;
|
||||||
|
|
||||||
// Shrink Vector's capacity:
|
// Shrink Vector's capacity:
|
||||||
// p_vect_shrink(v); // commented this out to make vect_clear behave more like the clear method in C++
|
// p_vect_shrink(v); // commented this out to make vect_clear behave more like
|
||||||
|
// the clear method in C++
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -973,7 +993,7 @@ static zvect_retval p_vect_destroy(c_vector v, uint32_t flags) {
|
||||||
// Vector data storage primitives:
|
// Vector data storage primitives:
|
||||||
|
|
||||||
// inline implementation for all put:
|
// inline implementation for all put:
|
||||||
static inline zvect_retval p_vect_put_at(c_vector const v, const void *value, const zvect_index i) {
|
static zvect_retval p_vect_put_at(ivector v, const void *value, const zvect_index i) {
|
||||||
// Check if the index passed is out of bounds:
|
// Check if the index passed is out of bounds:
|
||||||
zvect_index idx = i;
|
zvect_index idx = i;
|
||||||
if (!(v->flags & ZV_CIRCULAR)) {
|
if (!(v->flags & ZV_CIRCULAR)) {
|
||||||
|
@ -1003,7 +1023,7 @@ static inline zvect_retval p_vect_put_at(c_vector const v, const void *value, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// inline implementation for all add(s):
|
// inline implementation for all add(s):
|
||||||
static inline zvect_retval p_vect_add_at(c_vector const v, const void *value, const zvect_index i) {
|
static inline zvect_retval p_vect_add_at(ivector v, const void *value, const zvect_index i) {
|
||||||
zvect_index idx = i;
|
zvect_index idx = i;
|
||||||
|
|
||||||
// Get vector size:
|
// Get vector size:
|
||||||
|
@ -1122,7 +1142,7 @@ static inline zvect_retval p_vect_add_at(c_vector const v, const void *value, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the inline implementation for all the remove and pop
|
// This is the inline implementation for all the remove and pop
|
||||||
static inline zvect_retval p_vect_remove_at(c_vector const v, const zvect_index i, void **item) {
|
static inline zvect_retval p_vect_remove_at(ivector v, const zvect_index i, void **item) {
|
||||||
zvect_index idx = i;
|
zvect_index idx = i;
|
||||||
|
|
||||||
// Get the vector size:
|
// Get the vector size:
|
||||||
|
@ -1237,7 +1257,7 @@ static inline zvect_retval p_vect_remove_at(c_vector const v, const zvect_index
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the inline implementation for all the "delete" methods
|
// This is the inline implementation for all the "delete" methods
|
||||||
static inline zvect_retval p_vect_delete_at(c_vector const v,
|
static inline zvect_retval p_vect_delete_at(ivector v,
|
||||||
const zvect_index start,
|
const zvect_index start,
|
||||||
const zvect_index offset,
|
const zvect_index offset,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
|
@ -1260,13 +1280,13 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
|
||||||
zvect_index tot_items = start + offset;
|
zvect_index tot_items = start + offset;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*
|
/*
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: start %*u\n", 14, start);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: start %*u\n", 14, start);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: offset %*u\n", 14, offset);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: offset %*u\n", 14, offset);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: tot_items %*u\n", 14, tot_items);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: tot_items %*u\n", 14, tot_items);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: v->begin %*u\n", 14, v->begin);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: v->begin %*u\n", 14, v->begin);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: v->end %*u\n", 14, v->end);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: v->end %*u\n", 14, v->end);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: vsize %*u\n", 14, vsize);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: vsize %*u\n", 14, vsize);
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data);
|
log_msg(ZVLP_INFO, "p_vect_delete_at: data %*p\n", 14, v->data);
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
if ((vsize > 1) && (start < (vsize - 1)) && (tot_items < vsize) && (v->data != NULL)) {
|
if ((vsize > 1) && (start < (vsize - 1)) && (tot_items < vsize) && (v->data != NULL)) {
|
||||||
|
@ -1274,7 +1294,8 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* for (zvect_index ptrID = start; ptrID < start + offset; ptrID++)
|
/* for (zvect_index ptrID = start; ptrID < start + offset; ptrID++)
|
||||||
{
|
{
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_delete_at: data ptr %*p\n", 14, v->data + (v->begin + ptrID));
|
log_msg(ZVLP_INFO, "p_vect_delete_at: data ptr %*p\n", 14,
|
||||||
|
v->data + (v->begin + ptrID));
|
||||||
}*/
|
}*/
|
||||||
#endif
|
#endif
|
||||||
// Safe erase items?
|
// Safe erase items?
|
||||||
|
@ -1343,7 +1364,7 @@ static inline zvect_retval p_vect_delete_at(c_vector const v,
|
||||||
* Public method to request ZVector to
|
* Public method to request ZVector to
|
||||||
* shrink a vector.
|
* shrink a vector.
|
||||||
*/
|
*/
|
||||||
void vect_shrink(c_vector const v) {
|
void vect_shrink(ivector v) {
|
||||||
#if (ZVECT_THREAD_SAFE == 1)
|
#if (ZVECT_THREAD_SAFE == 1)
|
||||||
zvect_retval lock_owner = get_mutex_lock(v, 1);
|
zvect_retval lock_owner = get_mutex_lock(v, 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1365,23 +1386,24 @@ void vect_shrink(c_vector const v) {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
// Vector Structural Information report:
|
// Vector Structural Information report:
|
||||||
|
|
||||||
bool vect_is_empty(c_vector const v) {
|
int vect_is_empty(ivector v) {
|
||||||
return !p_vect_check(v) ? (p_vect_size(v) == 0) : (bool)ZVERR_VECTUNDEF;
|
return !p_vect_check(v) ? ((p_vect_size(v) == 0) ? TRUE : FALSE) : FALSE;
|
||||||
|
//return !p_vect_check(v) ? (p_vect_size(v) == 0) : (bool)ZVERR_VECTUNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
zvect_index vect_size(c_vector const v) {
|
zvect_index vect_size(ivector v) {
|
||||||
return !p_vect_check(v) ? p_vect_size(v) : 0;
|
return !p_vect_check(v) ? p_vect_size(v) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
zvect_index vect_max_size(c_vector const v) {
|
zvect_index vect_max_size(ivector v) {
|
||||||
return !p_vect_check(v) ? zvect_index_max : 0;
|
return (!p_vect_check(v) ? zvect_index_max : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_begin(c_vector const v) {
|
void *vect_begin(ivector v) {
|
||||||
return !p_vect_check(v) ? v->data[v->begin] : NULL;
|
return !p_vect_check(v) ? v->data[v->begin] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_end(c_vector const v) {
|
void *vect_end(ivector v) {
|
||||||
return !p_vect_check(v) ? v->data[v->end] : NULL;
|
return !p_vect_check(v) ? v->data[v->end] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1490,27 +1512,27 @@ void vect_lock_disable(void) {
|
||||||
locking_disabled = true;
|
locking_disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline zvect_retval p_vect_lock(c_vector const v) {
|
static inline zvect_retval p_vect_lock(ivector v) {
|
||||||
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v, 3);
|
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
zvect_retval vect_lock(c_vector const v) {
|
zvect_retval vect_lock(ivector v) {
|
||||||
return p_vect_lock(v);
|
return p_vect_lock(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline zvect_retval p_vect_unlock(c_vector const v) {
|
static inline zvect_retval p_vect_unlock(ivector v) {
|
||||||
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_unlock(v, 3);
|
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : get_mutex_unlock(v, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
zvect_retval vect_unlock(c_vector const v) {
|
zvect_retval vect_unlock(ivector v) {
|
||||||
return p_vect_unlock(v);
|
return p_vect_unlock(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline zvect_retval p_vect_trylock(c_vector const v) {
|
static inline zvect_retval p_vect_trylock(ivector v) {
|
||||||
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : check_mutex_trylock(v, 3);
|
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 0 : check_mutex_trylock(v, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
zvect_retval vect_trylock(c_vector const v) {
|
zvect_retval vect_trylock(ivector v) {
|
||||||
return p_vect_trylock(v);
|
return p_vect_trylock(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1531,11 +1553,12 @@ zvect_retval vect_sem_post(const c_vector v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static inline zvect_retval p_vect_wait_for_signal(const vector v) {
|
static inline zvect_retval p_vect_wait_for_signal(const c_vector v) {
|
||||||
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 : wait_for_signal(v, 3);
|
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 :
|
||||||
|
wait_for_signal(v, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline zvect_retval vect_wait_for_signal(const vector v) {
|
inline zvect_retval vect_wait_for_signal(const c_vector v) {
|
||||||
return p_vect_wait_for_signal(v);
|
return p_vect_wait_for_signal(v);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -1563,7 +1586,7 @@ zvect_retval vect_broadcast_signal(const c_vector v) {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
// Vector Data Storage functions:
|
// Vector Data Storage functions:
|
||||||
|
|
||||||
void vect_clear(c_vector const v) {
|
void vect_clear(ivector v) {
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -1590,10 +1613,9 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) {
|
void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) {
|
||||||
v->SfWpFunc = (void *)malloc(sizeof(void *));
|
// v->SfWpFunc = (void *)malloc(sizeof(void *));
|
||||||
if (v->SfWpFunc == NULL) {
|
// if (v->SfWpFunc == NULL)
|
||||||
p_throw_error(ZVERR_OUTOFMEM, NULL);
|
// p_throw_error(ZVERR_OUTOFMEM, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
// Set custom Safe Wipe function:
|
// Set custom Safe Wipe function:
|
||||||
v->SfWpFunc = f1;
|
v->SfWpFunc = f1;
|
||||||
|
@ -1602,7 +1624,8 @@ void vect_set_wipefunct(const c_vector v, void (*f1)(const void *, size_t)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an item at the END (top) of the vector
|
// Add an item at the END (top) of the vector
|
||||||
inline void vect_push(const c_vector v, const void *value) {
|
void vect_push(const c_vector v, const void *value) {
|
||||||
|
zvect_index vsize = 0;
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -1625,7 +1648,7 @@ inline void vect_push(const c_vector v, const void *value) {
|
||||||
// push will use index 0 and the rule in ZVector is
|
// push will use index 0 and the rule in ZVector is
|
||||||
// when we use index 0 we may need to expand on the
|
// when we use index 0 we may need to expand on the
|
||||||
// left. So let's check if we do for this vector:
|
// left. So let's check if we do for this vector:
|
||||||
zvect_index vsize = p_vect_size(v);
|
vsize = p_vect_size(v);
|
||||||
|
|
||||||
// Check if we need to expand on thr right side:
|
// Check if we need to expand on thr right side:
|
||||||
if ((v->end >= v->cap_right) && ((rval = p_vect_increase_capacity(v, 1)) != 0)) {
|
if ((v->end >= v->cap_right) && ((rval = p_vect_increase_capacity(v, 1)) != 0)) {
|
||||||
|
@ -1703,7 +1726,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an item at the FRONT of the vector
|
// Add an item at the FRONT of the vector
|
||||||
void vect_add_front(c_vector const v, const void *value) {
|
void vect_add_front(ivector v, const void *value) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -1741,7 +1764,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// inline implementation for all get(s):
|
// inline implementation for all get(s):
|
||||||
static inline void *p_vect_get_at(c_vector const v, const zvect_index i) {
|
static inline void *p_vect_get_at(ivector v, const zvect_index i) {
|
||||||
// Check if passed index is out of bounds:
|
// Check if passed index is out of bounds:
|
||||||
if (i >= p_vect_size(v)) {
|
if (i >= p_vect_size(v)) {
|
||||||
p_throw_error(ZVERR_IDXOUTOFBOUND, NULL);
|
p_throw_error(ZVERR_IDXOUTOFBOUND, NULL);
|
||||||
|
@ -1751,7 +1774,7 @@ static inline void *p_vect_get_at(c_vector const v, const zvect_index i) {
|
||||||
return v->data[v->begin + i];
|
return v->data[v->begin + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_get(c_vector const v) {
|
void *vect_get(ivector v) {
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
|
@ -1763,7 +1786,7 @@ void *vect_get(c_vector const v) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_get_at(c_vector const v, const zvect_index i) {
|
void *vect_get_at(ivector v, const zvect_index i) {
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
|
@ -1775,7 +1798,7 @@ void *vect_get_at(c_vector const v, const zvect_index i) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_get_front(c_vector const v) {
|
void *vect_get_front(ivector v) {
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (!rval) {
|
if (!rval) {
|
||||||
|
@ -1787,7 +1810,7 @@ void *vect_get_front(c_vector const v) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_put(c_vector const v, const void *value) {
|
void vect_put(ivector v, const void *value) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -1811,7 +1834,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_put_at(c_vector const v, const void *value, const zvect_index i) {
|
void vect_put_at(ivector v, const void *value, const zvect_index i) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -1835,7 +1858,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_put_front(c_vector const v, const void *value) {
|
void vect_put_front(ivector v, const void *value) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -1859,7 +1882,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void *vect_pop(c_vector const v) {
|
void *vect_pop(ivector v) {
|
||||||
void *item = NULL;
|
void *item = NULL;
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -1889,7 +1912,7 @@ JOB_DONE:
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_remove(c_vector const v) {
|
void *vect_remove(ivector v) {
|
||||||
void *item = NULL;
|
void *item = NULL;
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -1919,7 +1942,7 @@ JOB_DONE:
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_remove_at(c_vector const v, const zvect_index i) {
|
void *vect_remove_at(ivector v, const zvect_index i) {
|
||||||
void *item = NULL;
|
void *item = NULL;
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -1948,7 +1971,7 @@ JOB_DONE:
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vect_remove_front(c_vector const v) {
|
void *vect_remove_front(ivector v) {
|
||||||
void *item = NULL;
|
void *item = NULL;
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -1978,7 +2001,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete an item at the END of the vector
|
// Delete an item at the END of the vector
|
||||||
void vect_delete(c_vector const v) {
|
void vect_delete(ivector v) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -2027,8 +2050,9 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a range of items from "first_element" to "last_element" on the vector v
|
// Delete a range of items from "first_element" to "last_element" on the vector
|
||||||
void vect_delete_range(c_vector const v, const zvect_index first_element, const zvect_index last_element) {
|
// v
|
||||||
|
void vect_delete_range(ivector v, const zvect_index first_element, const zvect_index last_element) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -2054,7 +2078,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete an item at the BEGINNING of a vector v
|
// Delete an item at the BEGINNING of a vector v
|
||||||
void vect_delete_front(c_vector const v) {
|
void vect_delete_front(ivector v) {
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
goto JOB_DONE;
|
goto JOB_DONE;
|
||||||
|
@ -2084,7 +2108,7 @@ JOB_DONE:
|
||||||
// Vector Data Manipulation functions
|
// Vector Data Manipulation functions
|
||||||
#ifdef ZVECT_DMF_EXTENSIONS
|
#ifdef ZVECT_DMF_EXTENSIONS
|
||||||
|
|
||||||
void vect_swap(c_vector const v, const zvect_index i1, const zvect_index i2) {
|
void vect_swap(ivector v, const zvect_index i1, const zvect_index i2) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if (i1 == i2) {
|
if (i1 == i2) {
|
||||||
return;
|
return;
|
||||||
|
@ -2125,7 +2149,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_swap_range(c_vector const v, const zvect_index s1, const zvect_index e1, const zvect_index s2) {
|
void vect_swap_range(ivector v, const zvect_index s1, const zvect_index e1, const zvect_index s2) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if (s1 == s2) {
|
if (s1 == s2) {
|
||||||
return;
|
return;
|
||||||
|
@ -2174,7 +2198,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_rotate_left(c_vector const v, const zvect_index i) {
|
void vect_rotate_left(ivector v, const zvect_index i) {
|
||||||
|
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
|
@ -2230,7 +2254,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_rotate_right(c_vector const v, const zvect_index i) {
|
void vect_rotate_right(ivector v, const zvect_index i) {
|
||||||
// check if the vector exists:
|
// check if the vector exists:
|
||||||
zvect_retval rval = p_vect_check(v);
|
zvect_retval rval = p_vect_check(v);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -2287,7 +2311,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRADITIONAL_QSORT
|
#ifdef TRADITIONAL_QSORT
|
||||||
static inline zvect_index p_partition(vector v,
|
static inline zvect_index p_partition(c_vector v,
|
||||||
zvect_index low,
|
zvect_index low,
|
||||||
zvect_index high,
|
zvect_index high,
|
||||||
int (*compare_func)(const void *, const void *)) {
|
int (*compare_func)(const void *, const void *)) {
|
||||||
|
@ -2309,7 +2333,10 @@ static inline zvect_index p_partition(vector v,
|
||||||
return (i + 1);
|
return (i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void p_vect_qsort(vector v, zvect_index low, zvect_index high, int (*compare_func)(const void *, const void *)) {
|
static void p_vect_qsort(c_vector v,
|
||||||
|
zvect_index low,
|
||||||
|
zvect_index high,
|
||||||
|
int (*compare_func)(const void *, const void *)) {
|
||||||
if (low < high) {
|
if (low < high) {
|
||||||
zvect_index pi = p_partition(v, low, high, compare_func);
|
zvect_index pi = p_partition(v, low, high, compare_func);
|
||||||
p_vect_qsort(v, low, pi - 1, compare_func);
|
p_vect_qsort(v, low, pi - 1, compare_func);
|
||||||
|
@ -2423,7 +2450,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRADITIONAL_BINARY_SEARCH
|
#ifdef TRADITIONAL_BINARY_SEARCH
|
||||||
static bool p_standard_binary_search(vector v,
|
static bool p_standard_binary_search(c_vector v,
|
||||||
const void *key,
|
const void *key,
|
||||||
zvect_index *item_index,
|
zvect_index *item_index,
|
||||||
int (*f1)(const void *, const void *)) {
|
int (*f1)(const void *, const void *)) {
|
||||||
|
@ -2461,7 +2488,7 @@ static bool p_standard_binary_search(vector v,
|
||||||
// original design, most notably the use of custom compare
|
// original design, most notably the use of custom compare
|
||||||
// function that makes it suitable also to search through strings
|
// function that makes it suitable also to search through strings
|
||||||
// and other types of vectors.
|
// and other types of vectors.
|
||||||
static bool p_adaptive_binary_search(c_vector const v,
|
static bool p_adaptive_binary_search(ivector v,
|
||||||
const void *key,
|
const void *key,
|
||||||
zvect_index *item_index,
|
zvect_index *item_index,
|
||||||
int (*f1)(const void *, const void *)) {
|
int (*f1)(const void *, const void *)) {
|
||||||
|
@ -2540,7 +2567,7 @@ MONOBOUND:
|
||||||
}
|
}
|
||||||
#endif // ! TRADITIONAL_BINARY_SEARCH
|
#endif // ! TRADITIONAL_BINARY_SEARCH
|
||||||
|
|
||||||
bool vect_bsearch(c_vector const v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index) {
|
bool vect_bsearch(ivector v, const void *key, int (*f1)(const void *, const void *), zvect_index *item_index) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if ((key == NULL) || (f1 == NULL) || (p_vect_size(v) == 0)) {
|
if ((key == NULL) || (f1 == NULL) || (p_vect_size(v) == 0)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2588,7 +2615,7 @@ JOB_DONE:
|
||||||
* functions, the vect_add_ordered is an exception because it
|
* functions, the vect_add_ordered is an exception because it
|
||||||
* requires vect_bserach and vect_qsort to be available.
|
* requires vect_bserach and vect_qsort to be available.
|
||||||
*/
|
*/
|
||||||
void vect_add_ordered(c_vector const v, const void *value, int (*f1)(const void *, const void *)) {
|
void vect_add_ordered(ivector v, const void *value, int (*f1)(const void *, const void *)) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -2658,7 +2685,7 @@ JOB_DONE:
|
||||||
#ifdef ZVECT_SFMD_EXTENSIONS
|
#ifdef ZVECT_SFMD_EXTENSIONS
|
||||||
// Single Function Call Multiple Data operations extensions:
|
// Single Function Call Multiple Data operations extensions:
|
||||||
|
|
||||||
void vect_apply(c_vector const v, void (*f)(void *)) {
|
void vect_apply(ivector v, void (*f)(void *)) {
|
||||||
// Check Parameters:
|
// Check Parameters:
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -2691,7 +2718,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_apply_range(c_vector const v, void (*f)(void *), const zvect_index x, const zvect_index y) {
|
void vect_apply_range(ivector v, void (*f)(void *), const zvect_index x, const zvect_index y) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -2740,7 +2767,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_apply_if(c_vector const v1, c_vector const v2, void (*f1)(void *), bool (*f2)(void *, void *)) {
|
void vect_apply_if(ivector v1, ivector v2, void (*f1)(void *), bool (*f2)(void *, void *)) {
|
||||||
// Check parameters:
|
// Check parameters:
|
||||||
if (f1 == NULL || f2 == NULL) {
|
if (f1 == NULL || f2 == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -2782,7 +2809,7 @@ JOB_DONE:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vect_copy(c_vector const v1, c_vector const v2, const zvect_index s2, const zvect_index e2) {
|
void vect_copy(ivector v1, ivector v2, const zvect_index s2, const zvect_index e2) {
|
||||||
// check if the vectors v1 and v2 exist:
|
// check if the vectors v1 and v2 exist:
|
||||||
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -2846,11 +2873,7 @@ JOB_DONE:
|
||||||
* position s1).
|
* position s1).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vect_insert(c_vector const v1,
|
void vect_insert(ivector v1, ivector v2, const zvect_index s2, const zvect_index e2, const zvect_index s1) {
|
||||||
c_vector const v2,
|
|
||||||
const zvect_index s2,
|
|
||||||
const zvect_index e2,
|
|
||||||
const zvect_index s1) {
|
|
||||||
// check if the vectors v1 and v2 exist:
|
// check if the vectors v1 and v2 exist:
|
||||||
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -2949,11 +2972,11 @@ JOB_DONE:
|
||||||
* the end of it).
|
* the end of it).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
|
static inline zvect_retval p_vect_move(ivector v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
|
||||||
zvect_retval rval = 0;
|
zvect_retval rval = 0;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_move: move pointers set from v2 to v1\n");
|
log_msg(ZVLP_INFO, "p_vect_move: move pointers set from v2 to v1\n");
|
||||||
#endif
|
#endif
|
||||||
// We can only copy vectors with the same data_size!
|
// We can only copy vectors with the same data_size!
|
||||||
if (v1->data_size != v2->data_size) {
|
if (v1->data_size != v2->data_size) {
|
||||||
|
@ -2977,8 +3000,9 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, s2 = %*u, ee2 = %*u\n",
|
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u, "
|
||||||
|
"s2 = %*u, ee2 = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v2),
|
p_vect_capacity(v2),
|
||||||
10,
|
10,
|
||||||
|
@ -2992,7 +3016,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
10,
|
10,
|
||||||
ee2);
|
ee2);
|
||||||
|
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3010,7 +3034,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3021,7 +3045,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
10,
|
10,
|
||||||
p_vect_size(v1));
|
p_vect_size(v1));
|
||||||
|
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_move: ready to copy pointers set\n");
|
log_msg(ZVLP_INFO, "p_vect_move: ready to copy pointers set\n");
|
||||||
#endif
|
#endif
|
||||||
// Move v2 (from s2) in v1 at the end of v1:
|
// Move v2 (from s2) in v1 at the end of v1:
|
||||||
const void *rptr = NULL;
|
const void *rptr = NULL;
|
||||||
|
@ -3044,7 +3068,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
v1->end += ee2;
|
v1->end += ee2;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "p_vect_move: done copy pointers set\n");
|
log_msg(ZVLP_INFO, "p_vect_move: done copy pointers set\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Clean up v2 memory slots that no longer belong to v2:
|
// Clean up v2 memory slots that no longer belong to v2:
|
||||||
|
@ -3052,7 +3076,7 @@ static inline zvect_retval p_vect_move(c_vector const v1, c_vector v2, const zve
|
||||||
|
|
||||||
DONE_PROCESSING:
|
DONE_PROCESSING:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
"p_vect_move: v1 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3062,7 +3086,7 @@ DONE_PROCESSING:
|
||||||
v1->end,
|
v1->end,
|
||||||
10,
|
10,
|
||||||
p_vect_size(v1));
|
p_vect_size(v1));
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
"p_vect_move: v2 capacity = %*u, begin = %*u, end = %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v2),
|
p_vect_capacity(v2),
|
||||||
|
@ -3082,7 +3106,7 @@ DONE_PROCESSING:
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
// vect_move moves a portion of a vector (v2) into another (v1):
|
// vect_move moves a portion of a vector (v2) into another (v1):
|
||||||
void vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
|
void vect_move(ivector v1, c_vector v2, const zvect_index s2, const zvect_index e2) {
|
||||||
// check if the vectors v1 and v2 exist:
|
// check if the vectors v1 and v2 exist:
|
||||||
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -3095,10 +3119,10 @@ void vect_move(c_vector const v1, c_vector v2, const zvect_index s2, const zvect
|
||||||
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move: --- begin ---\n");
|
log_msg(ZVLP_INFO, "vect_move: --- begin ---\n");
|
||||||
#if (ZVECT_THREAD_SAFE == 1)
|
#if (ZVECT_THREAD_SAFE == 1)
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
log_msg(ZVLP_INFO, "vect_move: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
log_msg(ZVLP_INFO, "vect_move: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
||||||
#endif // ZVECT_THREAD_SAFE
|
#endif // ZVECT_THREAD_SAFE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3123,7 +3147,7 @@ DONE_PROCESSING:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move: --- end ---\n");
|
log_msg(ZVLP_INFO, "vect_move: --- end ---\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JOB_DONE:
|
JOB_DONE:
|
||||||
|
@ -3135,8 +3159,9 @@ JOB_DONE:
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
// vect_move_if moves a portion of a vector (v2) into another (v1) if f2 is true:
|
// vect_move_if moves a portion of a vector (v2) into another (v1) if f2 is
|
||||||
zvect_retval vect_move_if(c_vector const v1,
|
// true:
|
||||||
|
zvect_retval vect_move_if(ivector v1,
|
||||||
c_vector v2,
|
c_vector v2,
|
||||||
const zvect_index s2,
|
const zvect_index s2,
|
||||||
const zvect_index e2,
|
const zvect_index e2,
|
||||||
|
@ -3153,10 +3178,10 @@ zvect_retval vect_move_if(c_vector const v1,
|
||||||
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move_if: --- begin ---\n");
|
log_msg(ZVLP_INFO, "vect_move_if: --- begin ---\n");
|
||||||
#if (ZVECT_THREAD_SAFE == 1)
|
#if (ZVECT_THREAD_SAFE == 1)
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move_if: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
log_msg(ZVLP_INFO, "vect_move_if: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move_if: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
log_msg(ZVLP_INFO, "vect_move_if: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
||||||
#endif // ZVECT_THREAD_SAFE
|
#endif // ZVECT_THREAD_SAFE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3181,7 +3206,7 @@ DONE_PROCESSING:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_move_if: --- end ---\n");
|
log_msg(ZVLP_INFO, "vect_move_if: --- end ---\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JOB_DONE:
|
JOB_DONE:
|
||||||
|
@ -3198,7 +3223,7 @@ JOB_DONE:
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// vect_move_on_signal
|
// vect_move_on_signal
|
||||||
|
|
||||||
zvect_retval vect_move_on_signal(c_vector const v1,
|
zvect_retval vect_move_on_signal(ivector v1,
|
||||||
c_vector v2,
|
c_vector v2,
|
||||||
const zvect_index s2,
|
const zvect_index s2,
|
||||||
const zvect_index e2,
|
const zvect_index e2,
|
||||||
|
@ -3215,44 +3240,44 @@ zvect_retval vect_move_on_signal(c_vector const v1,
|
||||||
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
zvect_retval lock_owner1 = (locking_disabled || (v1->flags & ZV_NOLOCKING)) ? 0 : get_mutex_lock(v1, 1);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- start waiting ---\n");
|
log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- start waiting ---\n");
|
||||||
#endif
|
#endif
|
||||||
// wait until we get a signal
|
// wait until we get a signal
|
||||||
while (!(*f2)(v1, v2) && !(v2->status && (bool)ZVS_USR1_FLAG)) {
|
while (!(*f2)(v1, v2) && !(v2->status)) {
|
||||||
pthread_cond_wait(&(v2->cond), &(v2->lock));
|
pthread_cond_wait(&(v2->cond), &(v2->lock));
|
||||||
}
|
}
|
||||||
v2->status &= ~(ZVS_USR1_FLAG);
|
v2->status &= ~(ZVS_USR1_FLAG);
|
||||||
// v2->status |= ZVS_USR_FLAG;
|
// v2->status |= ZVS_USR_FLAG;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "Set status flag: %*i\n", 10, vect_check_status(v2, 1));
|
log_msg(ZVLP_MEDIUM, "Set status flag: %*i\n", 10, vect_check_status(v2, 1));
|
||||||
|
|
||||||
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- received signal ---\n");
|
log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- received signal ---\n");
|
||||||
|
|
||||||
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- begin ---\n");
|
log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- begin ---\n");
|
||||||
#endif
|
#endif
|
||||||
// Proceed with move items:
|
// Proceed with move items:
|
||||||
rval = p_vect_move(v1, v2, s2, e2);
|
rval = p_vect_move(v1, v2, s2, e2);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n");
|
log_msg(ZVLP_MEDIUM, "vect_move_on_signal: --- end ---\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v2->status &= ~(ZVS_USR1_FLAG);
|
v2->status &= ~(ZVS_USR1_FLAG);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "Reset status flag: %*i\n", 10, vect_check_status(v2, 1));
|
log_msg(ZVLP_MEDIUM, "Reset status flag: %*i\n", 10, vect_check_status(v2, 1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DONE_PROCESSING:
|
// DONE_PROCESSING:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "v1 owner? %*i\n", 10, lock_owner1);
|
log_msg(ZVLP_MEDIUM, "v1 owner? %*i\n", 10, lock_owner1);
|
||||||
#endif
|
#endif
|
||||||
if (lock_owner1) {
|
if (lock_owner1) {
|
||||||
get_mutex_unlock(v1, 1);
|
get_mutex_unlock(v1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_MEDIUM, "v2 owner? %*i\n", 10, lock_owner2);
|
log_msg(ZVLP_MEDIUM, "v2 owner? %*i\n", 10, lock_owner2);
|
||||||
#endif
|
#endif
|
||||||
rval = p_vect_delete_at(v2, s2, e2 - 1, 0);
|
rval = p_vect_delete_at(v2, s2, e2 - 1, 0);
|
||||||
if (lock_owner2) {
|
if (lock_owner2) {
|
||||||
|
@ -3271,7 +3296,7 @@ JOB_DONE:
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// vect_merge merges a vector (v2) into another (v1)
|
// vect_merge merges a vector (v2) into another (v1)
|
||||||
void vect_merge(c_vector const v1, c_vector v2) {
|
void vect_merge(ivector v1, c_vector v2) {
|
||||||
// check if the vector v1 exists:
|
// check if the vector v1 exists:
|
||||||
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
zvect_retval rval = p_vect_check(v1) | p_vect_check(v2);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
|
@ -3284,10 +3309,10 @@ void vect_merge(c_vector const v1, c_vector v2) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_merge: --- begin ---\n");
|
log_msg(ZVLP_INFO, "vect_merge: --- begin ---\n");
|
||||||
#if (ZVECT_THREAD_SAFE == 1)
|
#if (ZVECT_THREAD_SAFE == 1)
|
||||||
LOG_MOD(ZVLP_INFO, "vect_merge: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
log_msg(ZVLP_INFO, "vect_merge: lock_owner1 for vector v1: %*u\n", 10, lock_owner1);
|
||||||
LOG_MOD(ZVLP_INFO, "vect_merge: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
log_msg(ZVLP_INFO, "vect_merge: lock_owner2 for vector v2: %*u\n", 10, lock_owner2);
|
||||||
#endif // ZVECT_THREAD_SAFE
|
#endif // ZVECT_THREAD_SAFE
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
@ -3304,7 +3329,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"vect_merge: v2 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
"vect_merge: v2 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v2),
|
p_vect_capacity(v2),
|
||||||
|
@ -3314,7 +3339,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
|
||||||
v2->end,
|
v2->end,
|
||||||
10,
|
10,
|
||||||
p_vect_size(v2));
|
p_vect_size(v2));
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3332,7 +3357,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3351,7 +3376,7 @@ void vect_merge(c_vector const v1, c_vector v2) {
|
||||||
v1->end += p_vect_size(v2);
|
v1->end += p_vect_size(v2);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO,
|
log_msg(ZVLP_INFO,
|
||||||
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
"vect_merge: v1 capacity = %*u, begin = %*u, end: %*u, size = %*u\n",
|
||||||
10,
|
10,
|
||||||
p_vect_capacity(v1),
|
p_vect_capacity(v1),
|
||||||
|
@ -3384,7 +3409,7 @@ DONE_PROCESSING:
|
||||||
// free memory correctly.
|
// free memory correctly.
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LOG_MOD(ZVLP_INFO, "vect_merge: --- end ---\n");
|
log_msg(ZVLP_INFO, "vect_merge: --- end ---\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JOB_DONE:
|
JOB_DONE:
|
||||||
|
|
Loading…
Reference in New Issue