diff --git a/cvector.h b/cvector.h index b6eac22..af869be 100644 --- a/cvector.h +++ b/cvector.h @@ -40,7 +40,6 @@ #include /* for memmove */ #define cvector_clib_memmove memmove #endif -#include /* for size_t, ptrdiff_t */ /* NOTE: Similar to C's qsort and bsearch, you will receive a T* * for a vector of Ts. This means that you cannot use `free` directly @@ -435,21 +434,21 @@ typedef struct cvector_metadata_t { * @return the element at the specified position in the vector. */ #define cvector_at(vec, n) \ - ((vec)[(cvector_clib_assert((vec) && (ptrdiff_t)(n) < (ptrdiff_t)cvector_size(vec)), (n))]) + ((vec) ? (((int)(n) < 0 || (size_t)(n) >= cvector_size(vec)) ? NULL : &(vec)[n]) : NULL) /** * @brief cvector_front - returns a reference to the first element in the vector. Unlike member cvector_begin, which returns an iterator to this same element, this function returns a direct reference. * @return a reference to the first element in the vector container. */ #define cvector_front(vec) \ - (cvector_at(vec, 0)) + ((vec) ? ((cvector_size(vec) > 0) ? cvector_at(vec, 0) : NULL) : NULL) /** * @brief cvector_back - returns a reference to the last element in the vector.Unlike member cvector_end, which returns an iterator just past this element, this function returns a direct reference. * @return a reference to the last element in the vector. */ #define cvector_back(vec) \ - (cvector_at(vec, cvector_size(vec) - 1)) + ((vec) ? ((cvector_size(vec) > 0) ? cvector_at(vec, cvector_size(vec) - 1) : NULL) : NULL) /** * @brief cvector_resize - resizes the container to contain count elements. diff --git a/example.c b/example.c index d0fc05c..5313a04 100644 --- a/example.c +++ b/example.c @@ -32,20 +32,20 @@ int main(int argc, char *argv[]) { /* remove an element by specifying an array subscript */ cvector_erase(v, 2); - int twenty = cvector_at(v, 1); - printf("twenty : %d\n", twenty); + int *twenty = cvector_at(v, 1); + printf("twenty : %d\n", *twenty); - int front = cvector_front(v); - printf("front : %d\n", front); + int *front = cvector_front(v); + printf("front : %d\n", *front); - int back = cvector_back(v); - printf("back : %d\n", back); + int *back = cvector_back(v); + printf("back : %d\n", *back); /* remove an element from the back */ cvector_pop_back(v); back = cvector_back(v); - printf("back val after pop_back: %d\n", back); + printf("back val after pop_back: %d\n", *back); /* print out some stats about the vector */ printf("pointer : %p\n", (void *)v); diff --git a/unit-tests.c b/unit-tests.c index efc18ef..fa63042 100644 --- a/unit-tests.c +++ b/unit-tests.c @@ -26,11 +26,13 @@ UTEST(test, cvector_back) { ASSERT_TRUE(cvector_size(v) == 2); - ASSERT_TRUE(cvector_back(v) == 1); + int *back = cvector_back(v); + ASSERT_TRUE(*back == 1); cvector_push_back(v, 2); - ASSERT_TRUE(cvector_back(v) == 2); + back = cvector_back(v); + ASSERT_TRUE(*back == 2); cvector_free(v); } @@ -42,10 +44,12 @@ UTEST(test, cvector_front) { ASSERT_TRUE(cvector_size(v) == 2); - ASSERT_TRUE(cvector_front(v) == 0); + int *front = cvector_front(v); + ASSERT_TRUE(*front == 0); cvector_erase(v, 0); - ASSERT_TRUE(cvector_front(v) == 1); + front = cvector_front(v); + ASSERT_TRUE(*front == 1); cvector_free(v); } @@ -63,10 +67,18 @@ UTEST(test, vector_at) { if (v) { int i = 0; for (; i < (int)cvector_size(v); i++) { - ASSERT_TRUE(cvector_at(v, i) == i); + ASSERT_TRUE(*cvector_at(v, i) == i); } } + /* test non-exists position */ + int pos_non_exists = 999; + ASSERT_TRUE(cvector_at(v, pos_non_exists) == NULL); + + /* remove last element*/ + cvector_pop_back(v); + ASSERT_TRUE(cvector_at(v, 4) == NULL); + cvector_free(v); }