/ externals / zycore / tests / Vector.cpp
Vector.cpp
  1  /***************************************************************************************************
  2  
  3    Zyan Core Library (Zycore-C)
  4  
  5    Original Author : Florian Bernd
  6  
  7   * Permission is hereby granted, free of charge, to any person obtaining a copy
  8   * of this software and associated documentation files (the "Software"), to deal
  9   * in the Software without restriction, including without limitation the rights
 10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11   * copies of the Software, and to permit persons to whom the Software is
 12   * furnished to do so, subject to the following conditions:
 13   *
 14   * The above copyright notice and this permission notice shall be included in all
 15   * copies or substantial portions of the Software.
 16   *
 17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 23   * SOFTWARE.
 24  
 25  ***************************************************************************************************/
 26  
 27  /**
 28   * @file
 29   * @brief   Tests the `ZyanVector` implementation.
 30   */
 31  
 32  #include <time.h>
 33  #include <gtest/gtest.h>
 34  #include <Zycore/Comparison.h>
 35  #include <Zycore/Vector.h>
 36  
 37  /* ============================================================================================== */
 38  /* Fixtures                                                                                       */
 39  /* ============================================================================================== */
 40  
 41  /* ---------------------------------------------------------------------------------------------- */
 42  /* VectorTestBase                                                                                 */
 43  /* ---------------------------------------------------------------------------------------------- */
 44  
 45  /**
 46   * @brief   Implements a fixture-class that provides an initialized `ZyanVector` instance for
 47   *          `ZyanU64` values.
 48   */
 49  class VectorTestBase : public ::testing::TestWithParam<bool>
 50  {
 51  protected:
 52      static const ZyanUSize m_test_size = 100;
 53      ZyanBool               m_has_fixed_capacity;
 54      ZyanVector             m_vector;
 55      std::vector<ZyanU64>   m_buffer;
 56  protected:
 57      void SetUp() override
 58      {
 59          m_has_fixed_capacity = GetParam();
 60  
 61          if (!m_has_fixed_capacity)
 62          {
 63              ASSERT_EQ(ZyanVectorInit(&m_vector, sizeof(ZyanU64), m_test_size, 
 64                  reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
 65          } else
 66          {
 67              m_buffer.reserve(m_test_size);
 68              ASSERT_EQ(ZyanVectorInitCustomBuffer(&m_vector, sizeof(ZyanU64), m_buffer.data(),
 69                  m_test_size, reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), 
 70                  ZYAN_STATUS_SUCCESS);
 71          }
 72      }
 73  
 74      void TearDown() override
 75      {
 76          EXPECT_EQ(ZyanVectorDestroy(&m_vector), ZYAN_STATUS_SUCCESS);
 77      }
 78  };
 79  
 80  /* ---------------------------------------------------------------------------------------------- */
 81  /* VectorTestFilled                                                                               */
 82  /* ---------------------------------------------------------------------------------------------- */
 83  
 84  /**
 85   * @brief   Implements a fixture-class that provides an initialized `ZyanVector` instance which
 86   *          is filled with `ZyanU64` values from 0..100.
 87   */
 88  class VectorTestFilled : public VectorTestBase
 89  {
 90  protected:
 91      void SetUp() override
 92      {
 93          VectorTestBase::SetUp();
 94  
 95          if (m_has_fixed_capacity)
 96          {
 97              m_buffer.resize(m_test_size);
 98          }
 99          for (ZyanU64 i = 0; i < m_test_size; ++i)
100          {
101              ASSERT_EQ(ZyanVectorPushBack(&m_vector, &i), ZYAN_STATUS_SUCCESS);
102          }
103      }
104  };
105  
106  /* ---------------------------------------------------------------------------------------------- */
107  
108  /* ============================================================================================== */
109  /* Helper functions                                                                               */
110  /* ============================================================================================== */
111  
112  /**
113   * @brief   A dummy constructor for `ZyanU64` objects.
114   *
115   * @param   object  A pointer to the object.
116   *
117   * @return  A zyan status code.
118   */
119  static ZyanStatus InitZyanU64(ZyanU64* object)
120  {
121      *object = 1337;
122      return ZYAN_STATUS_SUCCESS;
123  }
124  
125  /**
126   * @brief   A dummy destructor for `ZyanU16` objects.
127   *
128   * @param   object  A pointer to the object.
129   *
130   * @return  A zyan status code.
131   */
132  static ZyanStatus FreeZyanU16(ZyanU16* object)
133  {
134      *object = 0;
135      return ZYAN_STATUS_SUCCESS;
136  }
137  
138  /* ============================================================================================== */
139  /* Tests                                                                                          */
140  /* ============================================================================================== */
141  
142  TEST(VectorTest, InitBasic)
143  {
144      ZyanVector vector;
145  
146      ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0, 
147          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
148      EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
149      EXPECT_EQ(vector.growth_factor, ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR);
150      EXPECT_EQ(vector.shrink_threshold, ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD);
151      EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
152      EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
153      EXPECT_EQ(vector.element_size, sizeof(ZyanU64));
154      EXPECT_NE(vector.data, ZYAN_NULL);
155      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
156  
157      // Custom capacity
158      EXPECT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU16), 10, 
159          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
160      EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_MAX(ZYAN_VECTOR_MIN_CAPACITY, 10)));
161      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
162  }
163  
164  TEST(VectorTest, InitAdvanced)
165  {
166      ZyanVector vector;
167  
168      ASSERT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 0, 
169          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1, 0),
170          ZYAN_STATUS_SUCCESS);
171      EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
172      EXPECT_EQ(vector.growth_factor, 1);
173      EXPECT_EQ(vector.shrink_threshold, 0);
174      EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
175      EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
176      EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
177      EXPECT_NE(vector.data, ZYAN_NULL);
178      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
179  
180      // Custom capacity
181      EXPECT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 10, 
182          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1, 0),
183          ZYAN_STATUS_SUCCESS);
184      EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_MAX(ZYAN_VECTOR_MIN_CAPACITY, 10)));
185      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
186  }
187  
188  TEST(VectorTest, InitCustomBuffer)
189  {
190      ZyanVector vector;
191  
192      ZyanU16 buffer[32];
193      EXPECT_EQ(ZyanVectorInitCustomBuffer(&vector, sizeof(ZyanU16), &buffer, 0, 
194          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_INVALID_ARGUMENT);
195      ASSERT_EQ(ZyanVectorInitCustomBuffer(&vector, sizeof(ZyanU16), &buffer,
196          ZYAN_ARRAY_LENGTH(buffer), reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), 
197          ZYAN_STATUS_SUCCESS);
198      EXPECT_EQ(vector.allocator, ZYAN_NULL);
199      EXPECT_EQ(vector.growth_factor, 1);
200      EXPECT_EQ(vector.shrink_threshold, 0);
201      EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
202      EXPECT_EQ(vector.capacity, ZYAN_ARRAY_LENGTH(buffer));
203      EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
204      EXPECT_EQ(vector.data, &buffer);
205      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
206  }
207  
208  TEST(VectorTest, Destructor)
209  {
210      ZyanVector vector;
211  
212      ZyanU16 buffer[16];
213      ASSERT_EQ(ZyanVectorInitCustomBuffer(&vector, sizeof(ZyanU16), &buffer,
214          ZYAN_ARRAY_LENGTH(buffer), reinterpret_cast<ZyanMemberProcedure>(&FreeZyanU16)), 
215          ZYAN_STATUS_SUCCESS);
216      
217      for (ZyanUSize i = 0; i < ZYAN_ARRAY_LENGTH(buffer); ++i)
218      {
219          const auto element = static_cast<ZyanU16>(i) + 0;
220          ASSERT_EQ(ZyanVectorPushBack(&vector, &element), ZYAN_STATUS_SUCCESS);
221          ASSERT_EQ(buffer[i], element);
222      }
223  
224      ASSERT_EQ(ZyanVectorPopBack(&vector), ZYAN_STATUS_SUCCESS);
225      ASSERT_EQ(buffer[15], 0);
226  
227      ASSERT_EQ(ZyanVectorDeleteRange(&vector, 12, 3), ZYAN_STATUS_SUCCESS);
228      ASSERT_EQ(buffer[12], 0);
229      ASSERT_EQ(buffer[13], 0);
230      ASSERT_EQ(buffer[14], 0);
231  
232      ASSERT_EQ(ZyanVectorClear(&vector), ZYAN_STATUS_SUCCESS);
233      for (ZyanUSize i : buffer)
234      {
235          ASSERT_EQ(i, 0);
236      }
237  
238      for (ZyanUSize i = 0; i < ZYAN_ARRAY_LENGTH(buffer); ++i)
239      {
240          const auto element = static_cast<ZyanU16>(i) + 1;
241          ASSERT_EQ(ZyanVectorPushBack(&vector, &element), ZYAN_STATUS_SUCCESS);
242          ASSERT_EQ(buffer[i], element);
243      }
244  
245      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
246      for (ZyanUSize i : buffer)
247      {
248          ASSERT_EQ(i, 0);
249      }
250  }
251  
252  TEST(VectorTest, TestGrowingAndShrinking)
253  {
254      ZyanVector vector;
255  
256      ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0,
257          reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
258  
259      for (ZyanU64 i = 0; i < 100; ++i)
260      {
261          ZyanUSize expected_capacity = vector.capacity;
262          if (expected_capacity < (i + 1))
263          {
264              expected_capacity = (expected_capacity + 1) * vector.growth_factor;
265          }
266          ASSERT_EQ(ZyanVectorPushBack(&vector, &i), ZYAN_STATUS_SUCCESS);
267          ASSERT_EQ(vector.capacity, expected_capacity);
268      }
269  
270      for (ZyanU64 i = 100; i > 0; --i)
271      {
272          const auto index = static_cast<ZyanUSize>(i - 1);
273  
274          ZyanUSize expected_capacity = vector.capacity;
275          if ((vector.shrink_threshold != 0) && (index * vector.shrink_threshold < vector.capacity))
276          {
277              expected_capacity = ZYAN_MAX(1, (ZyanUSize)(index * vector.growth_factor));
278          }
279          ASSERT_EQ(ZyanVectorDelete(&vector, index), ZYAN_STATUS_SUCCESS);
280          ASSERT_EQ(vector.capacity, expected_capacity);
281      }
282  
283      EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
284  }
285  
286  TEST_P(VectorTestFilled, ElementAccess)
287  {
288      static const ZyanU64 element_in = 1337;
289      const ZyanU64* element_dummy;
290      ZyanU64* element_out_mut;
291  
292      EXPECT_EQ(ZyanVectorSet(&m_vector, m_vector.size, &element_in),
293          ZYAN_STATUS_OUT_OF_RANGE);
294      EXPECT_EQ(ZyanVectorSet(&m_vector, m_vector.size - 1, &element_in),
295          ZYAN_STATUS_SUCCESS);
296  
297      EXPECT_EQ(ZyanVectorGetPointer(&m_vector, m_vector.size,
298          reinterpret_cast<const void**>(&element_dummy)), ZYAN_STATUS_OUT_OF_RANGE);
299      EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, m_vector.size - 1), element_in);
300  
301      EXPECT_EQ(ZyanVectorGetPointerMutable(&m_vector, m_vector.size,
302          reinterpret_cast<void**>(&element_out_mut)), ZYAN_STATUS_OUT_OF_RANGE);
303      EXPECT_EQ(ZyanVectorGetPointerMutable(&m_vector, m_vector.size - 1,
304          reinterpret_cast<void**>(&element_out_mut)), ZYAN_STATUS_SUCCESS);
305      EXPECT_EQ(*element_out_mut, element_in);
306      *element_out_mut = 42;
307      EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, m_vector.size - 1), 42);
308  
309      if (m_has_fixed_capacity)
310      {
311          EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, m_vector.size - 1),
312              m_buffer[m_vector.size - 1]);
313      }
314  }
315  
316  TEST_P(VectorTestFilled, PushPop)
317  {
318      static const ZyanU64 element_in = 1337;
319      const ZyanUSize size = m_vector.size;
320  
321      if (!m_has_fixed_capacity)
322      {
323          EXPECT_EQ(ZyanVectorPushBack(&m_vector, &element_in), ZYAN_STATUS_SUCCESS);
324          EXPECT_EQ(m_vector.size, size + 1);
325          EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, size), element_in);
326          EXPECT_EQ(ZyanVectorPopBack(&m_vector), ZYAN_STATUS_SUCCESS);
327          EXPECT_EQ(m_vector.size, size);
328      } else
329      {
330          EXPECT_EQ(ZyanVectorPushBack(&m_vector, &element_in), ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE);
331          EXPECT_EQ(m_vector.size, size);
332          EXPECT_EQ(ZyanVectorPopBack(&m_vector), ZYAN_STATUS_SUCCESS);
333          EXPECT_EQ(m_vector.size, size - 1);
334          EXPECT_EQ(ZyanVectorPushBack(&m_vector, &element_in), ZYAN_STATUS_SUCCESS);
335          EXPECT_EQ(m_vector.size, size);
336          EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, size - 1), element_in);
337      }
338  }
339  
340  TEST_P(VectorTestFilled, Insert)
341  {
342      static const ZyanU64 elements[4] =
343      {
344          1337, 1338, 1339, 1340
345      };
346      const ZyanUSize count = ZYAN_ARRAY_LENGTH(elements);
347  
348      if (m_has_fixed_capacity)
349      {
350          const ZyanUSize size_temp = m_vector.size;
351          EXPECT_EQ(ZyanVectorInsertRange(&m_vector, size_temp / 2, &elements, count),
352              ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE);
353          EXPECT_EQ(ZyanVectorResize(&m_vector, size_temp - count), ZYAN_STATUS_SUCCESS);
354          EXPECT_EQ(m_vector.size, size_temp - count);
355      }
356  
357      const ZyanUSize size = m_vector.size;
358      const ZyanUSize half = (size / 2);
359  
360      EXPECT_EQ(ZyanVectorInsertRange(&m_vector, half, &elements, ZYAN_ARRAY_LENGTH(elements)),
361          ZYAN_STATUS_SUCCESS);
362      EXPECT_EQ(m_vector.size, size + count);
363      for (ZyanUSize i = 0; i < m_vector.size; ++i)
364      {
365          const ZyanU64 element_out = ZYAN_VECTOR_GET(ZyanU64, &m_vector, i);
366  
367          if ((i >= half) && (i < half + count))
368          {
369              EXPECT_EQ(element_out, elements[i - half]);
370          } else
371          if (i < half)
372          {
373              EXPECT_EQ(element_out, i);
374          } else
375          {
376              EXPECT_EQ(element_out, i - count);
377          }
378      }
379  }
380  
381  TEST_P(VectorTestFilled, Delete)
382  {
383      EXPECT_EQ(ZyanVectorDeleteRange(&m_vector, m_vector.size, 1), ZYAN_STATUS_OUT_OF_RANGE);
384      EXPECT_EQ(ZyanVectorDeleteRange(&m_vector, 1, m_vector.size), ZYAN_STATUS_OUT_OF_RANGE);
385  
386      const ZyanUSize size = m_vector.size;
387      const ZyanUSize half = (size / 2);
388      const ZyanUSize count = (half / 2);
389  
390      EXPECT_EQ(ZyanVectorDeleteRange(&m_vector, half, count), ZYAN_STATUS_SUCCESS);
391      EXPECT_EQ(m_vector.size, size - count);
392      for (ZyanUSize i = 0; i < m_vector.size; ++i)
393      {
394          const ZyanU64 element_out = ZYAN_VECTOR_GET(ZyanU64, &m_vector, i);
395  
396          if ((i >= half) && (i < half + count))
397          {
398              EXPECT_EQ(element_out, i + count);
399          } else
400          if (i < half)
401          {
402              EXPECT_EQ(element_out, i);
403          } else
404          {
405              EXPECT_EQ(element_out, i - count);
406          }
407      }
408  }
409  
410  TEST_P(VectorTestFilled, Find)
411  {
412      ZyanISize index;
413      ZyanU64 element_in = m_vector.size / 2;
414      EXPECT_EQ(ZyanVectorFind(&m_vector, &element_in, &index,
415          reinterpret_cast<ZyanEqualityComparison>(&ZyanEqualsNumeric64)), ZYAN_STATUS_TRUE);
416      EXPECT_EQ(static_cast<ZyanU64>(index), element_in);
417  
418      element_in = 1337;
419      EXPECT_EQ(ZyanVectorFind(&m_vector, &element_in, &index,
420          reinterpret_cast<ZyanEqualityComparison>(&ZyanEqualsNumeric64)), ZYAN_STATUS_FALSE);
421      EXPECT_EQ(index, -1);
422  
423      // Edge cases
424      EXPECT_EQ(ZyanVectorFindEx(&m_vector, &element_in, &index,
425          reinterpret_cast<ZyanEqualityComparison>(&ZyanEqualsNumeric64), 0, 0),
426          ZYAN_STATUS_FALSE);
427      EXPECT_EQ(ZyanVectorFindEx(&m_vector, &element_in, &index,
428          reinterpret_cast<ZyanEqualityComparison>(&ZyanEqualsNumeric64), 0, m_vector.size + 1),
429          ZYAN_STATUS_OUT_OF_RANGE);
430      EXPECT_EQ(ZyanVectorFindEx(&m_vector, &element_in, &index,
431          reinterpret_cast<ZyanEqualityComparison>(&ZyanEqualsNumeric64), 1, m_vector.size),
432          ZYAN_STATUS_OUT_OF_RANGE);
433  }
434  
435  TEST_P(VectorTestBase, BinarySearch)
436  {
437      EXPECT_EQ(ZyanVectorReserve(&m_vector, 100), ZYAN_STATUS_SUCCESS);
438      for (ZyanUSize i = 0; i < 100; ++i)
439      {
440          const ZyanU64 element = rand() % 100;
441  
442          ZyanUSize index;
443          const ZyanStatus status = ZyanVectorBinarySearch(&m_vector, &element, &index,
444              reinterpret_cast<ZyanComparison>(&ZyanCompareNumeric64));
445          EXPECT_EQ(ZYAN_SUCCESS(status), ZYAN_TRUE);
446          EXPECT_EQ(ZyanVectorInsert(&m_vector, index, &element), ZYAN_STATUS_SUCCESS);
447      }
448      EXPECT_EQ(m_vector.size, static_cast<ZyanUSize>(100));
449  
450      ZyanU64 element_out = ZYAN_VECTOR_GET(ZyanU64, &m_vector, 0);
451      for (ZyanUSize i = 1; i < m_vector.size; ++i)
452      {
453          const ZyanU64 value = element_out;
454          element_out = ZYAN_VECTOR_GET(ZyanU64, &m_vector, i);
455          EXPECT_GE(element_out, value);
456      }
457  
458      // Edge cases
459      const ZyanU64 element_in = 1337;
460      ZyanUSize index;
461      EXPECT_EQ(ZyanVectorBinarySearchEx(&m_vector, &element_in, &index,
462          reinterpret_cast<ZyanComparison>(&ZyanCompareNumeric64), 0, 101),
463          ZYAN_STATUS_OUT_OF_RANGE);
464      EXPECT_EQ(ZyanVectorBinarySearchEx(&m_vector, &element_in, &index,
465          reinterpret_cast<ZyanComparison>(&ZyanCompareNumeric64), 1, 100),
466          ZYAN_STATUS_OUT_OF_RANGE);
467  }
468  
469  TEST_P(VectorTestBase, Emplace)
470  {
471      ZyanU64* element_new;
472  
473      for (ZyanUSize i = 0; i < 10; ++i)
474      {
475          EXPECT_EQ(ZyanVectorEmplace(&m_vector, reinterpret_cast<void**>(&element_new), 
476              reinterpret_cast<ZyanMemberFunction>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
477          *element_new = i;
478      }
479      EXPECT_EQ(m_vector.size, static_cast<ZyanUSize>(10));
480  
481      for (ZyanUSize i = 0; i < m_vector.size; ++i)
482      {
483          EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, i), i);
484      }
485  
486      EXPECT_EQ(ZyanVectorEmplaceEx(&m_vector, 5, reinterpret_cast<void**>(&element_new),
487          reinterpret_cast<ZyanMemberFunction>(&InitZyanU64)), ZYAN_STATUS_SUCCESS);
488      EXPECT_EQ(*element_new, 1337);
489      EXPECT_EQ(ZYAN_VECTOR_GET(ZyanU64, &m_vector, 5), 1337);
490  }
491  
492  TEST_P(VectorTestFilled, SwapElements)
493  {
494      EXPECT_EQ(m_vector.capacity, m_vector.size);
495  
496      // Edge cases
497      EXPECT_EQ(ZyanVectorSwapElements(&m_vector, 0, m_vector.size), ZYAN_STATUS_OUT_OF_RANGE);
498      EXPECT_EQ(ZyanVectorSwapElements(&m_vector, m_vector.size, 0), ZYAN_STATUS_OUT_OF_RANGE);
499      EXPECT_EQ(ZyanVectorSwapElements(&m_vector, 0, m_vector.size - 1),
500          ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE);
501  
502      // Free space for the temporary element
503      EXPECT_EQ(ZyanVectorPopBack(&m_vector), ZYAN_STATUS_SUCCESS);
504  
505      // Retrieve element pointers
506      const ZyanU64* element_first;
507      EXPECT_EQ(ZyanVectorGetPointer(&m_vector, 0, reinterpret_cast<const void**>(&element_first)),
508          ZYAN_STATUS_SUCCESS);
509      const ZyanU64* element_second;
510      EXPECT_EQ(ZyanVectorGetPointer(&m_vector, m_vector.size - 1, 
511          reinterpret_cast<const void**>(&element_second)), ZYAN_STATUS_SUCCESS);
512  
513      const ZyanU64 values_before[2] = { *element_first, *element_second };
514      EXPECT_EQ(ZyanVectorSwapElements(&m_vector, 0, m_vector.size - 1), ZYAN_STATUS_SUCCESS);
515      const ZyanU64 values_after [2] = { *element_first, *element_second };
516  
517      EXPECT_EQ(values_before[0], values_after[1]);
518      EXPECT_EQ(values_before[1], values_after[0]);
519  }
520  
521  INSTANTIATE_TEST_SUITE_P(Param, VectorTestBase, ::testing::Values(false, true));
522  INSTANTIATE_TEST_SUITE_P(Param, VectorTestFilled, ::testing::Values(false, true));
523  
524  /* ---------------------------------------------------------------------------------------------- */
525  
526  /* ============================================================================================== */
527  /* Entry point                                                                                    */
528  /* ============================================================================================== */
529  
530  int main(int argc, char **argv)
531  {
532      time_t t;
533      srand(static_cast<unsigned>(time(&t)));
534  
535      ::testing::InitGoogleTest(&argc, argv);
536      return RUN_ALL_TESTS();
537  }
538  
539  /* ============================================================================================== */