olaf@424: /* olaf@424: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. olaf@424: * olaf@424: * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. olaf@424: * olaf@424: * Redistribution and use in source and binary forms, with or without olaf@424: * modification, are permitted provided that the following conditions are met: olaf@424: * olaf@424: * 1. Redistributions of source code must retain the above copyright olaf@424: * notice, this list of conditions and the following disclaimer. olaf@424: * olaf@424: * 2. Redistributions in binary form must reproduce the above copyright olaf@424: * notice, this list of conditions and the following disclaimer in the olaf@424: * documentation and/or other materials provided with the distribution. olaf@424: * olaf@424: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" olaf@424: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE olaf@424: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE olaf@424: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE olaf@424: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR olaf@424: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF olaf@424: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS olaf@424: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN olaf@424: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) olaf@424: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE olaf@424: * POSSIBILITY OF SUCH DAMAGE. olaf@424: */ universe@453: /** universe@453: * \file tree.h universe@453: * \brief Interface for tree implementations. universe@453: * \author Olaf Wintermann universe@453: * \author Mike Becker universe@453: * \version 3.0 universe@453: * \copyright 2-Clause BSD License universe@453: */ olaf@424: olaf@424: #ifndef UCX_TREE_H olaf@424: #define UCX_TREE_H olaf@424: olaf@424: #include olaf@424: #include olaf@424: #include "allocator.h" olaf@424: olaf@424: #ifdef __cplusplus olaf@424: extern "C" { olaf@424: #endif olaf@424: universe@453: /** universe@453: * Adds a sibling to the current tree node. universe@453: * universe@453: * In case your struct does not have a \p prev or a \p parent pointer, universe@453: * specify a negative location. The location of the \p next pointer is universe@453: * mandatory. universe@453: * universe@453: * \attention Do not use this function to add siblings in a tree where the universe@453: * nodes store a pointer to the last sibling because that would not be modified by this function. universe@453: * universe@453: * \remark If yo do not provide a location to the parent pointer, a call to this function is universe@453: * effectively the same as a call to cx_linked_list_add(). universe@453: * universe@453: * @param node a pointer to the node universe@453: * @param loc_prev the location of a \c prev pointer within your node struct universe@453: * @param loc_next the location of a \c next pointer within your node struct universe@453: * @param loc_parent the location of a \c parent pointer within your node struct universe@453: * @param new_node the new node that shall be added as a sibling universe@453: */ universe@453: void cx_tree_add_sibling(void *node, universe@453: ptrdiff_t loc_prev, ptrdiff_t loc_next, universe@453: ptrdiff_t loc_parent, universe@453: void *new_node) universe@453: __attribute__((__nonnull__)); universe@453: universe@453: /** universe@453: * Adds a node to the list of children. universe@453: * universe@453: * \par Example with a full structure universe@453: * A full tree node structure may look like this: universe@453: * \code universe@453: * typedef struct MyTreeNode MyTreeNode; universe@453: * struct MyTreeNode { universe@453: * MyTreeNode* parent; universe@453: * MyTreeNode* first_child; universe@453: * MyTreeNode* last_child; universe@453: * MyTreeNode* prev_sibling; universe@453: * MyTreeNode* next_sibling; universe@453: * // ...contents... universe@453: * } universe@453: * \endcode universe@453: * Adding a new child to a node with the above structure can be performed with the following call: universe@453: * \code universe@453: * MyTreeNode *node, *child; // given universe@453: * cx_tree_add_child(&node->first_child, &node->last_child, universe@453: * offsetof(MyTreeNode, prev_sibling), offsetof(MyTreeNode, next_sibling), universe@453: * child, offsetof(MyTreeNode, parent), node); universe@453: * \endcode universe@453: * universe@453: * \par Example with a reduced structure universe@453: * The minimal reasonable structure with parent pointer looks like this: universe@453: * \code universe@453: * typedef struct MyTreeNode MyTreeNode; universe@453: * struct MyTreeNode { universe@453: * MyTreeNode* parent; universe@453: * MyTreeNode* children; universe@453: * MyTreeNode* next_sibling; universe@453: * // ...contents... universe@453: * } universe@453: * \endcode universe@453: * This simplifies the function call to: universe@453: * \code universe@453: * MyTreeNode *node, *child; // given universe@453: * cx_tree_add_child(&node->children, NULL, -1, offsetof(MyTreeNode, next_sibling), universe@453: * child, offsetof(MyTreeNode, parent), node); universe@453: * \endcode universe@453: * universe@453: * \remark If your tree structure does not possess a parent pointer, a call to this function is universe@453: * effectively the same as a call to cx_linked_list_add(). universe@453: * universe@453: * @param children_begin a pointer to the begin node pointer (if your list has one) universe@453: * @param children_end a pointer to the end node pointer (if your list has one) universe@453: * @param loc_prev the location of a \c prev pointer within your node struct universe@453: * @param loc_next the location of a \c next pointer within your node struct universe@453: * @param new_node a pointer to the node that shall be appended universe@453: * @param loc_parent the location of a \c parent pointer within your node struct universe@453: * @param parent the parent node universe@453: */ universe@453: void cx_tree_add_child(void **children_begin, void **children_end, universe@453: ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, universe@453: ptrdiff_t loc_parent, void *parent) universe@453: __attribute__((__nonnull__ (5))); olaf@424: olaf@424: olaf@424: #ifdef __cplusplus universe@453: } /* extern "C" */ olaf@424: #endif olaf@424: olaf@424: #endif /* UCX_TREE_H */ olaf@424: