Skip to content

Commit

Permalink
Tài liệu doxygen cho gvec_t
Browse files Browse the repository at this point in the history
  • Loading branch information
bangoc committed Jan 11, 2022
1 parent c0bb5e4 commit eaa213e
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 22 deletions.
15 changes: 11 additions & 4 deletions base/gtype.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
/*
(C) 2021 Nguyen Ba Ngoc (bangoc)
*/

#ifndef BASE_GTYPE_H_
#define BASE_GTYPE_H_

/* (C) 2021 Nguyen Ba Ngoc (bangoc) */

/** @file
* @brief Định nghĩa kiểu ::gtype và các thành phần bổ trợ.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/**
* \headerfile "cgen.h"
* Kiểu dữ liệu cơ bản của các cấu trúc dữ liệu được triển khai.
* ::gtype có thể thay thế cho 1 nhóm kiểu dữ liệu.
*/
typedef union generic_type {
long l;
double d;
Expand Down
4 changes: 2 additions & 2 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT =
INPUT ="." "./base"

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down Expand Up @@ -982,7 +982,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.

USE_MDFILE_AS_MAINPAGE =
USE_MDFILE_AS_MAINPAGE = ./README.md

#---------------------------------------------------------------------------
# Configuration options related to source browsing
Expand Down
136 changes: 120 additions & 16 deletions gvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/* (C) Nguyen Ba Ngoc 2021 */

/** @file
* @brief Vec-tơ (mảng cấp phát động) của các giá trị gtype.
* @brief Vec-tơ (còn được gọi là mảng động) của các giá trị ::gtype.
*
* Có thể truy cập ngẫu nhiên đến 1 phần tử bất kỳ trong vec-tơ
* theo chỉ số và sắp xếp nhanh vec-tơ tương tự như mảng.
Expand All @@ -18,23 +18,42 @@

/**
* \headerfile "cgen.h"
* Cấu trúc lưu các thông tin điều khiển vec-tơ.
* Cấu trúc biểu diễn vec-tơ của các giá trị ::gtype.
*
* Các macros điều khiển:
*
* #gvec_size(v) - Trả về size của vec-tơ.
* #gvec_size(v) - Kích thước của v.
*
* #gvec_capacity(v) - Trả về capacity của vec-tơ.
* #gvec_capacity(v) - Dung lượng của v.
*
* #gvec_arr(v) - Mảng các phần tử của v.
*
* #gvec_elem(v, i) - Phần tử thứ i của v.
*
* #gvec_elem_idx(v, elem_ptr) - Chỉ số của phần tử được trỏ tới bởi
* elem_ptr trong v.
*
* #gvec_append(v, val) - Thêm val vào sau phần tử cuối cùng trong v.
*
* #gvec_remove(v, idx) - Xóa phần tử có chỉ số idx khỏi v.
*
* #gvec_set_capacity(v, cap) - Chủ động thiết lập dung lượng cho v.
*
* #gvec_free(v) - Giải phóng bộ nhớ được cấp phát cho v.
*
* #gvec_qsort(v, cmp) - Sắp xếp các phần tử của v bằng qsort với hàm so sánh cmp.
*
* #gvec_traverse(cur, v) - Duyệt các phần tử của v theo chiều thuận.
*/
typedef struct gvec_s {
/**
* Mảng cơ sở lưu các đối tượng gtype
* Mảng cơ sở lưu các đối tượng ::gtype
*/
arr_t(gtype) arr;

/**
* Con trỏ tới hàm giải phóng dữ liệu được quản lý qua đối tượng
* gtype trong mảng. Nếu != NULL thì hàm được gọi khi giải phóng
* ::gtype trong mảng. Nếu != NULL thì hàm được gọi khi giải phóng
* bộ nhớ của vec-tơ, nếu ngược lại (== NULL) thì các gọi hàm được
* bỏ qua.
*/
Expand All @@ -45,39 +64,93 @@ typedef struct gvec_s {
* Hàm tạo đối tượng vec-tơ.
*
* @param cap (capacity) Dung lượng ban đầu của vec-tơ.
* @param free_value con trỏ hàm giải phóng bộ nhớ bên ngoài đối tượng gtype.
* Sử dụng NULL nếu không có bộ nhớ bên ngoài.
*
* @param free_value con trỏ hàm giải phóng bộ nhớ bên ngoài được gắn
* với đối tượng ::gtype. Sử dụng NULL nếu không có bộ nhớ bên ngoài.
* @return Trả về đối tượng tạo được nếu thành công hoặc NULL_PTR nếu thất bại.
* \memberof gvec_s
*/
gvec_t gvec_create(int cap, gtype_free_t free_value);

/**
* Trả về kích thước (size) của vec-tơ. Trong vec-tơ size là
* số lượng phần tử mảng đã sử dụng, còn capacity là số lượng phần tử
* đã cấp phát cho mảng cơ sở (arr), size luôn luôn <= cap.
* Trong vec-tơ size là số lượng phần tử mảng đã sử dụng,
* còn capacity là số lượng phần tử đã được cấp phát cho
* mảng cơ sở (arr), size luôn luôn <= cap.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @return Trả về kích thước (size) của vec-tơ, giá trị có kiểu long.
*/
#define gvec_size(v) (arr_size((v)->arr))

/**
* Trả về dung lượng (capacity) của vec-tơ. Trong vec-tơ size là
* số lượng phần tử mảng đã sử dụng, còn capacity là số lượng phần tử
* đã cấp phát cho mảng cơ sở (arr), size luôn luôn <= cap.
* Trong vec-tơ size là số lượng phần tử mảng đã sử dụng,
* còn capacity là số lượng phần tử đã được cấp phát cho
* mảng cơ sở (arr), size luôn luôn <= cap.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @return Trả về dung lượng (capacity) của vec-tơ, giá trị có kiểu long.
*/
#define gvec_capacity(v) (arr_capacity((v)->arr))

/**
* Giao diện mảng của vec-tơ.
* \code{.c}
* gvec_arr(v)[0]; \\ Phần tử đầu tiên của vec-tơ v.
* \endcode
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @return Trả về con trỏ tới phần tử đầu tiên của mảng (kiểu ::gtype *)
*/
#define gvec_arr(v) (ARR((v)->arr))

/**
* Chỉ định phần tử của vec-tơ bằng chỉ số.
* \code{.c}
* gvec_elem(v, 0); \\ Phần tử đầu tiên của vec-tơ v.
* \endcode
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param i Chỉ số của phần tử, là số nguyên và < #gvec_size(v).
* @return Phần tử có chỉ số i trong vec-tơ v, kết quả là lvalue có kiểu ::gtype.
*/
#define gvec_elem(v, i) ((gvec_arr(v))[(i)])
#define gvec_elem_idx(v, elem) ((long)((elem) - gvec_arr(v)))

/**
* Chỉ số của phần tử trong vec-tơ.
* \code{.c}
* gvec_elem_idx(&gvec_elem(v, i)) == i;
* \endcode
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param elem_ptr Con trỏ tới 1 phần tử hợp lệ trong vec-tơ.
* @return Chỉ số của phần tử được trỏ tới bởi elem_ptr.
*/
#define gvec_elem_idx(v, elem_ptr) ((long)((elem_ptr) - gvec_arr(v)))

/**
* Thêm giá trị val vào sau phần tử cuối cùng trong v và tăng kích thước lên 1.
* Nếu kích thước hiện tại bằng dung lượng thì mảng được cấp phát lại với kích
* thước lớn hơn trước khi thêm val.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param val Giá trị được thêm vào vec-tơ v.
* @return Không trả về giá trị.
*/
#define gvec_append(v, val) \
do { \
arr_append((v)->arr, val); \
} while (0)

/**
* Xóa phần tử có chỉ số idx khỏi vec-tơ v. Nếu v->free_value != NULL
* thì gọi hàm v->free_value(gvec_elem(v, i)) - Giải phóng bộ nhớ
* được gắn với đối tượng được xóa.
* Nếu idx là chỉ số không hợp lệ thì không có thay đổi gì, nếu ngược lại
* thì các phần tử có chỉ số > idx được dịch sang trái 1 vị trí, và kích
* thước vec-tơ được giảm đi 1 đơn vị.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param idx Chỉ số phần tử được xóa.
*/
#define gvec_remove(v, idx) \
do { \
gtype *_arr = ARR((v)->arr); \
Expand All @@ -94,6 +167,15 @@ gvec_t gvec_create(int cap, gtype_free_t free_value);
arr_set_size((v)->arr, _sz - 1); \
} while (0)

/**
* Chủ động thiết lập dung lượng cho vec-tơ v. Nếu dung lượng
* mới < kích thược hiện tại của vec-tơ thì không làm gì, nếu
* ngược lại thì cấp phát lại mảng với dung lượng = cap.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param cap Dung lượng mới.
* @return Không trả về giá trị.
*/
#define gvec_set_capacity(v, cap) \
do { \
int _sz = arr_size((v)->arr); \
Expand All @@ -103,6 +185,13 @@ gvec_t gvec_create(int cap, gtype_free_t free_value);
arr_set_capacity((v)->arr, (cap)); \
}

/**
* Giải phóng bộ nhớ được cấp phát cho v và các vùng nhớ ngoài
* được gắn với các phần tử của vec-tơ nếu có (v->free_value != NULL).
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @return Không trả về giá trị.
*/
#define gvec_free(v) \
do{ \
if ((v)->free_value) { \
Expand All @@ -116,9 +205,24 @@ gvec_t gvec_create(int cap, gtype_free_t free_value);
free(v); \
} while (0)

/**
* Sắp xếp các phần tử của vec-tơ.
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param cmp Con trỏ tới hàm so sách các đối tượng ::gtype được lưu trong vec-tơ.
* Đối số cmp có kiểu như hàm so sánh cho qsort (stdlib.h).
* @return Không trả về giá trị.
*/
#define gvec_qsort(v, cmp) \
qsort(ARR((v)->arr), gvec_size(v), sizeof(gtype), cmp)

/**
* Duyệt tuần tự các phần tử của vec-tơ
*
* @param v Con trỏ tới đối tượng vec-tơ (có kiểu gvec_t).
* @param cur Con trỏ tới phần tự hiện tại của vec-tơ trong vòng lặp,
* có kiểu ::gtype *.
*/
#define gvec_traverse(cur, v) \
for (gtype *cur = gvec_arr(v), *end = gvec_arr(v) + gvec_size(v); cur < end; ++cur)

Expand Down
7 changes: 7 additions & 0 deletions src/gvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@

gvec_t gvec_create(int cap, gtype_free_t free_value) {
gvec_t v = malloc(sizeof(struct gvec_s));
if (!v) {
return NULL_PTR;
}
v->arr = arr_create(cap, gtype);
if (!v->arr) {
free(v);
return NULL_PTR;
}
v->free_value = free_value;
return v;
}

0 comments on commit eaa213e

Please sign in to comment.