src/cx/iterator.h

changeset 494
6ce8cfa10a96
child 495
2856c74e18ba
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/cx/iterator.h	Sat Jan 22 17:15:14 2022 +0100
     1.3 @@ -0,0 +1,121 @@
     1.4 +/*
     1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 + *
     1.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     1.8 + *
     1.9 + * Redistribution and use in source and binary forms, with or without
    1.10 + * modification, are permitted provided that the following conditions are met:
    1.11 + *
    1.12 + *   1. Redistributions of source code must retain the above copyright
    1.13 + *      notice, this list of conditions and the following disclaimer.
    1.14 + *
    1.15 + *   2. Redistributions in binary form must reproduce the above copyright
    1.16 + *      notice, this list of conditions and the following disclaimer in the
    1.17 + *      documentation and/or other materials provided with the distribution.
    1.18 + *
    1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.29 + * POSSIBILITY OF SUCH DAMAGE.
    1.30 + */
    1.31 +/**
    1.32 + * \file iterator.h
    1.33 + * \brief Interface for iterator implementations.
    1.34 + * \author Mike Becker
    1.35 + * \author Olaf Wintermann
    1.36 + * \version 3.0
    1.37 + * \copyright 2-Clause BSD License
    1.38 + */
    1.39 +
    1.40 +#ifndef UCX_ITERATOR_H
    1.41 +#define UCX_ITERATOR_H
    1.42 +
    1.43 +#include "common.h"
    1.44 +
    1.45 +/**
    1.46 + * Iterator value type.
    1.47 + * An iterator points to a certain element in an (possibly unbounded) chain of elements.
    1.48 + * Iterators that are based on collections (which have a defined "first" element), are supposed
    1.49 + * to be "position-aware", which means that they keep track of the current index within the collection.
    1.50 + *
    1.51 + * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
    1.52 + * iterator is based on a collection and the underlying collection is mutated (elements added or removed),
    1.53 + * the iterator becomes invalid (regardless of what cxIteratorValid() returns) and MUST be re-obtained
    1.54 + * from the collection.
    1.55 + */
    1.56 +typedef struct cx_iterator_s CxIterator;
    1.57 +
    1.58 +/**
    1.59 + * Internal iterator struct - use CxIterator.
    1.60 + */
    1.61 +struct cx_iterator_s {
    1.62 +    /**
    1.63 +     * If the iterator is position-aware, contains the index of the element in the underlying collection.
    1.64 +     * Otherwise, this field is usually uninitialized.
    1.65 +     */
    1.66 +    size_t index;
    1.67 +    /**
    1.68 +     * Internal data.
    1.69 +     */
    1.70 +    void *data;
    1.71 +
    1.72 +    /**
    1.73 +     * True iff the iterator points to valid data.
    1.74 +     */
    1.75 +    bool (*valid)(CxIterator const *) __attribute__ ((__nonnull__));
    1.76 +
    1.77 +    /**
    1.78 +     * Returns a pointer to the current element.
    1.79 +     */
    1.80 +    void *(*current)(CxIterator const *) __attribute__ ((__nonnull__));
    1.81 +
    1.82 +    /**
    1.83 +     * Advances the iterator.
    1.84 +     */
    1.85 +    void (*next)(CxIterator *) __attribute__ ((__nonnull__));
    1.86 +};
    1.87 +
    1.88 +/**
    1.89 + * Checks if the iterator points to valid data.
    1.90 + *
    1.91 + * This is especially false for past-the-end iterators.
    1.92 + *
    1.93 + * @param iter the iterator
    1.94 + * @return true iff the iterator points to valid data
    1.95 + */
    1.96 +__attribute__ ((__nonnull__))
    1.97 +static inline bool cxIteratorValid(CxIterator const *iter) {
    1.98 +    return iter->valid(iter);
    1.99 +}
   1.100 +
   1.101 +/**
   1.102 + * Returns a pointer to the current element.
   1.103 + *
   1.104 + * The behavior is undefined if this iterator is invalid.
   1.105 + *
   1.106 + * @param iter the iterator
   1.107 + * @return a pointer to the current element
   1.108 + */
   1.109 +__attribute__ ((__nonnull__))
   1.110 +static inline void *cxIteratorCurrent(CxIterator const *iter) {
   1.111 +    return iter->current(iter);
   1.112 +}
   1.113 +
   1.114 +/**
   1.115 + * Advances the iterator to the next element.
   1.116 + *
   1.117 + * @param iter the iterator
   1.118 + */
   1.119 +__attribute__ ((__nonnull__))
   1.120 +static inline void cxIteratorNext(CxIterator *iter) {
   1.121 +    iter->next(iter);
   1.122 +}
   1.123 +
   1.124 +#endif /* UCX_ITERATOR_H */

mercurial