# HG changeset patch # User Mike Becker # Date 1684672676 -7200 # Node ID 8c6edaccaef154089dcea37de817e31036b567db # Parent 0d5447230044ed4981f2b1eae12e9756814da7a8 add empty map implementation - fixes #259 diff -r 0d5447230044 -r 8c6edaccaef1 src/CMakeLists.txt --- a/src/CMakeLists.txt Sun May 21 14:04:34 2023 +0200 +++ b/src/CMakeLists.txt Sun May 21 14:37:56 2023 +0200 @@ -7,6 +7,7 @@ linked_list.c tree.c buffer.c + map.c hash_key.c hash_map.c basic_mempool.c diff -r 0d5447230044 -r 8c6edaccaef1 src/cx/map.h --- a/src/cx/map.h Sun May 21 14:04:34 2023 +0200 +++ b/src/cx/map.h Sun May 21 14:37:56 2023 +0200 @@ -158,6 +158,8 @@ void *value; }; +extern CxMap *const cxEmptyMap; + /** * Advises the map to store copies of the objects (default mode of operation). * diff -r 0d5447230044 -r 8c6edaccaef1 src/map.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/map.c Sun May 21 14:37:56 2023 +0200 @@ -0,0 +1,90 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cx/map.h" + +// + +static void cx_empty_map_noop(__attribute__((__unused__)) CxMap *map) { + // this is a noop, but MUST be implemented +} + +static void *cx_empty_map_get( + __attribute__((__unused__)) CxMap const *map, + __attribute__((__unused__)) CxHashKey key +) { + return NULL; +} + +static bool cx_empty_map_iter_valid(__attribute__((__unused__)) void const *iter) { + return false; +} + +static CxIterator cx_empty_map_iterator(struct cx_map_s const *map) { + CxIterator iter = {0}; + iter.src_handle = map; + iter.base.valid = cx_empty_map_iter_valid; + return iter; +} + +static CxMutIterator cx_empty_map_miterator(struct cx_map_s *map) { + CxMutIterator iter = {0}; + iter.src_handle = map; + iter.base.valid = cx_empty_map_iter_valid; + return iter; +} + +static struct cx_map_class_s cx_empty_map_class = { + cx_empty_map_noop, + cx_empty_map_noop, + NULL, + cx_empty_map_get, + NULL, + cx_empty_map_iterator, + cx_empty_map_iterator, + cx_empty_map_iterator, + cx_empty_map_miterator, + cx_empty_map_miterator, + cx_empty_map_miterator, +}; + +CxMap cx_empty_map = { + NULL, + NULL, + 0, + 0, + NULL, + NULL, + NULL, + false, + &cx_empty_map_class +}; + +CxMap * const cxEmptyMap = &cx_empty_map; + +// diff -r 0d5447230044 -r 8c6edaccaef1 tests/test_map.cpp --- a/tests/test_map.cpp Sun May 21 14:04:34 2023 +0200 +++ b/tests/test_map.cpp Sun May 21 14:37:56 2023 +0200 @@ -472,3 +472,51 @@ cxMapDestroy(map); EXPECT_TRUE(allocator.verify()); } + +TEST(EmptyMap, Size) { + auto map = cxEmptyMap; + + EXPECT_EQ(map->size, 0); +} + +TEST(EmptyMap, Iterator) { + auto map = cxEmptyMap; + + auto it1 = cxMapIterator(map); + auto it2 = cxMapIteratorValues(map); + auto it3 = cxMapIteratorKeys(map); + auto it4 = cxMapMutIterator(map); + auto it5 = cxMapMutIteratorValues(map); + auto it6 = cxMapMutIteratorKeys(map); + + EXPECT_FALSE(cxIteratorValid(it1)); + EXPECT_FALSE(cxIteratorValid(it2)); + EXPECT_FALSE(cxIteratorValid(it3)); + EXPECT_FALSE(cxIteratorValid(it4)); + EXPECT_FALSE(cxIteratorValid(it5)); + EXPECT_FALSE(cxIteratorValid(it6)); + + int c = 0; + cx_foreach(void*, data, it1) c++; + cx_foreach(void*, data, it2) c++; + cx_foreach(void*, data, it3) c++; + cx_foreach(void*, data, it4) c++; + cx_foreach(void*, data, it5) c++; + cx_foreach(void*, data, it6) c++; + EXPECT_EQ(c, 0); +} + +TEST(EmptyMap, NoOps) { + auto map = cxEmptyMap; + + ASSERT_NO_FATAL_FAILURE(cxMapClear(map)); + ASSERT_NO_FATAL_FAILURE(cxMapRehash(map)); + ASSERT_NO_FATAL_FAILURE(cxMapDestroy(map)); +} + +TEST(EmptyMap, Get) { + auto map = cxEmptyMap; + + CxHashKey key = cx_hash_key_str("test"); + EXPECT_EQ(cxMapGet(map, key), nullptr); +}