src/cx/iterator.h

Sun, 21 May 2023 14:03:21 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 21 May 2023 14:03:21 +0200
changeset 704
35f06c5eeb0e
parent 695
eb1884a8b096
child 740
378578666c83
permissions
-rw-r--r--

add empty list implementation - fixes #258

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 /**
    29  * \file iterator.h
    30  * \brief Interface for iterator implementations.
    31  * \author Mike Becker
    32  * \author Olaf Wintermann
    33  * \version 3.0
    34  * \copyright 2-Clause BSD License
    35  */
    37 #ifndef UCX_ITERATOR_H
    38 #define UCX_ITERATOR_H
    40 #include "common.h"
    42 /**
    43  * The base of mutating and non-mutating iterators.
    44  */
    45 struct cx_iterator_base_s {
    46     /**
    47      * True iff the iterator points to valid data.
    48      */
    49     __attribute__ ((__nonnull__))
    50     bool (*valid)(void const *);
    52     /**
    53      * Returns a pointer to the current element.
    54      *
    55      * When valid returns false, the behavior of this function is undefined.
    56      */
    57     __attribute__ ((__nonnull__))
    58     void *(*current)(void const *);
    60     /**
    61      * Original implementation in case the function needs to be wrapped.
    62      */
    63     __attribute__ ((__nonnull__))
    64     void *(*current_impl)(void const *);
    66     /**
    67      * Advances the iterator.
    68      *
    69      * When valid returns false, the behavior of this function is undefined.
    70      */
    71     __attribute__ ((__nonnull__))
    72     void (*next)(void *);
    74     /**
    75      * Flag current element for removal, if possible.
    76      *
    77      * When valid returns false, the behavior of this function is undefined.
    78      */
    79     __attribute__ ((__nonnull__))
    80     bool (*flag_removal)(void *);
    82     /**
    83      * Indicates whether this iterator may remove elements.
    84      */
    85     bool mutating;
    87     /**
    88      * Internal flag for removing the current element when advancing.
    89      */
    90     bool remove;
    91 };
    93 /**
    94  * Internal iterator struct - use CxMutIterator.
    95  */
    96 struct cx_mut_iterator_s {
    98     /**
    99      * The base properties of this iterator.
   100      */
   101     struct cx_iterator_base_s base;
   103     /**
   104      * Handle for the current element, if required.
   105      */
   106     void *elem_handle;
   108     /**
   109      * Handle for the source collection, if any.
   110      */
   111     void *src_handle;
   113     /**
   114      * Field for storing a key-value pair.
   115      * May be used by iterators that iterate over k/v-collections.
   116      */
   117     struct {
   118         /**
   119          * A pointer to the key.
   120          */
   121         void const *key;
   122         /**
   123          * A pointer to the value.
   124          */
   125         void *value;
   126     } kv_data;
   128     /**
   129      * Field for storing a slot number.
   130      * May be used by iterators that iterate over multi-bucket collections.
   131      */
   132     size_t slot;
   134     /**
   135      * If the iterator is position-aware, contains the index of the element in the underlying collection.
   136      * Otherwise, this field is usually uninitialized.
   137      */
   138     size_t index;
   139 };
   141 /**
   142  * Mutating iterator value type.
   143  *
   144  * An iterator points to a certain element in an (possibly unbounded) chain of elements.
   145  * Iterators that are based on collections (which have a defined "first" element), are supposed
   146  * to be "position-aware", which means that they keep track of the current index within the collection.
   147  *
   148  * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
   149  * iterator is based on a collection and the underlying collection is mutated by other means than this iterator
   150  * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns)
   151  * and MUST be re-obtained from the collection.
   152  *
   153  * @see CxIterator
   154  */
   155 typedef struct cx_mut_iterator_s CxMutIterator;
   157 /**
   158  * Internal iterator struct - use CxIterator.
   159  */
   160 struct cx_iterator_s {
   162     /**
   163      * The base properties of this iterator.
   164      */
   165     struct cx_iterator_base_s base;
   167     /**
   168      * Handle for the current element, if required.
   169      */
   170     void *elem_handle;
   172     /**
   173      * Handle for the source collection, if any.
   174      */
   175     void const *src_handle;
   177     /**
   178      * Field for storing a key-value pair.
   179      * May be used by iterators that iterate over k/v-collections.
   180      */
   181     struct {
   182         /**
   183          * A pointer to the key.
   184          */
   185         void const *key;
   186         /**
   187          * A pointer to the value.
   188          */
   189         void *value;
   190     } kv_data;
   192     /**
   193      * Field for storing a slot number.
   194      * May be used by iterators that iterate over multi-bucket collections.
   195      */
   196     size_t slot;
   198     /**
   199      * If the iterator is position-aware, contains the index of the element in the underlying collection.
   200      * Otherwise, this field is usually uninitialized.
   201      */
   202     size_t index;
   203 };
   205 /**
   206  * Iterator value type.
   207  * An iterator points to a certain element in an (possibly unbounded) chain of elements.
   208  * Iterators that are based on collections (which have a defined "first" element), are supposed
   209  * to be "position-aware", which means that they keep track of the current index within the collection.
   210  *
   211  * @note Objects that are pointed to by an iterator are always mutable through that iterator. However,
   212  * this iterator cannot mutate the collection itself (add or remove elements) and any mutation of the
   213  * collection by other means make this iterator invalid (regardless of what cxIteratorValid() returns).
   214  *
   215  * @see CxMutIterator
   216  */
   217 typedef struct cx_iterator_s CxIterator;
   219 /**
   220  * Checks if the iterator points to valid data.
   221  *
   222  * This is especially false for past-the-end iterators.
   223  *
   224  * @param iter the iterator
   225  * @return true iff the iterator points to valid data
   226  */
   227 #define cxIteratorValid(iter) (iter).base.valid(&(iter))
   229 /**
   230  * Returns a pointer to the current element.
   231  *
   232  * The behavior is undefined if this iterator is invalid.
   233  *
   234  * @param iter the iterator
   235  * @return a pointer to the current element
   236  */
   237 #define cxIteratorCurrent(iter) (iter).base.current(&iter)
   239 /**
   240  * Advances the iterator to the next element.
   241  *
   242  * @param iter the iterator
   243  */
   244 #define cxIteratorNext(iter) (iter).base.next(&iter)
   246 /**
   247  * Flags the current element for removal.
   248  *
   249  * @param iter the iterator
   250  * @return false if this iterator cannot remove the element
   251  */
   252 #define cxIteratorFlagRemoval(iter) (iter).base.flag_removal(&iter)
   254 /**
   255  * Loops over an iterator.
   256  * @param type the type of the elements
   257  * @param elem the name of the iteration variable
   258  * @param iter the iterator
   259  */
   260 #define cx_foreach(type, elem, iter) \
   261 for (type elem; cxIteratorValid(iter) && (elem = (type)cxIteratorCurrent(iter)) != NULL ; cxIteratorNext(iter))
   263 #endif // UCX_ITERATOR_H

mercurial