src/cx/iterator.h

Tue, 04 Oct 2022 19:25:07 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 04 Oct 2022 19:25:07 +0200
changeset 591
7df0bcaecffa
parent 551
2946e13c89a4
child 628
1e2be40f0cb5
permissions
-rw-r--r--

fix over-optimization of strstr

1. it's actually less performant to frequently read bytes
from an array instead of using the native word length
2. the SBO buffer should be local and not static to allow
multi-threading usage

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2021 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.
 */
/**
 * \file iterator.h
 * \brief Interface for iterator implementations.
 * \author Mike Becker
 * \author Olaf Wintermann
 * \version 3.0
 * \copyright 2-Clause BSD License
 */

#ifndef UCX_ITERATOR_H
#define UCX_ITERATOR_H

#include "common.h"

/**
 * Internal iterator struct - use CxIterator.
 */
struct cx_iterator_s {
    /**
     * True iff the iterator points to valid data.
     */
    __attribute__ ((__nonnull__))
    bool (*valid)(struct cx_iterator_s const *);

    /**
     * Returns a pointer to the current element.
     */
    __attribute__ ((__nonnull__))
    void *(*current)(struct cx_iterator_s const *);

    /**
     * Advances the iterator.
     */
    __attribute__ ((__nonnull__))
    void (*next)(struct cx_iterator_s *);

    /**
     * Handle for the current element, if required.
     */
    void *elem_handle;

    /**
     * Handle for the source collection, if any.
     */
    void *src_handle;

    /**
     * Field for storing a key-value pair.
     * May be used by iterators that iterate over k/v-collections.
     */
    struct {
        /**
         * A pointer to the key.
         */
        void *key;
        /**
         * A pointer to the value.
         */
        void *value;
    } kv_data;

    /**
     * Field for storing a slot number.
     * May be used by iterators that iterate over multi-bucket collections.
     */
    size_t slot;

    /**
     * If the iterator is position-aware, contains the index of the element in the underlying collection.
     * Otherwise, this field is usually uninitialized.
     */
    size_t index;

    /**
     * Users may set this to true, if the current element shall be removed from the underlying collection
     * when the iterator advances.
     * Has no effect on iterators that are not based on a collection.
     */
    bool remove;
};

/**
 * Iterator value type.
 * An iterator points to a certain element in an (possibly unbounded) chain of elements.
 * Iterators that are based on collections (which have a defined "first" element), are supposed
 * to be "position-aware", which means that they keep track of the current index within the collection.
 *
 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
 * iterator is based on a collection and the underlying collection is mutated (elements added or removed),
 * the iterator becomes invalid (regardless of what cxIteratorValid() returns) and MUST be re-obtained
 * from the collection.
 */
typedef struct cx_iterator_s CxIterator;

/**
 * Checks if the iterator points to valid data.
 *
 * This is especially false for past-the-end iterators.
 *
 * @param iter a pointer to the iterator
 * @return true iff the iterator points to valid data
 */
__attribute__ ((__nonnull__))
static inline bool cxIteratorValid(CxIterator const *iter) {
    return iter->valid(iter);
}

/**
 * Returns a pointer to the current element.
 *
 * The behavior is undefined if this iterator is invalid.
 *
 * @param iter a pointer to the iterator
 * @return a pointer to the current element
 */
__attribute__ ((__nonnull__))
static inline void *cxIteratorCurrent(CxIterator const *iter) {
    return iter->current(iter);
}

/**
 * Advances the iterator to the next element.
 *
 * @param iter a pointer to the iterator
 */
__attribute__ ((__nonnull__))
static inline void cxIteratorNext(CxIterator *iter) {
    iter->next(iter);
}

/**
 * Loops over an iterator.
 * @param type the type of the elements
 * @param elem the name of the iteration variable
 * @param iter the iterator
 */
#define cx_foreach(type, elem, iter) \
for (type elem; cxIteratorValid(&iter) && (elem = (type)cxIteratorCurrent(&iter)) != NULL ; cxIteratorNext(&iter)) // NOLINT(bugprone-macro-parentheses)

#endif /* UCX_ITERATOR_H */

mercurial