From edf693f2daad92f7dbf468dabc7c76ec01568e9c Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Thu, 5 Nov 2026 18:15:24 +0800 Subject: [libbase][adt] Add ilist node options --- libbase/include/core/adt/ilist_node_options.h | 244 ++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 libbase/include/core/adt/ilist_node_options.h (limited to 'libbase/include/core') diff --git a/libbase/include/core/adt/ilist_node_options.h b/libbase/include/core/adt/ilist_node_options.h new file mode 100644 index 0000000..d26a6b8 --- /dev/null +++ b/libbase/include/core/adt/ilist_node_options.h @@ -0,0 +1,244 @@ +/* + RCC-Project + + Copyright (C) 2026 Richard Qin + + This file is part of RCC-Project. + + RCC-Project is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) any + later version. + + RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + RCC-Project; see the file COPYING. If not see + . +*/ + +//===- core/adt/ilist_node_options.h - ilist_node Options -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LIBBASE_ADT_ILIST_NODE_OPTIONS_H +#define LIBBASE_ADT_ILIST_NODE_OPTIONS_H + +#include + +namespace libbase +{ + +template class ilist_node_base; +template class ilist_base; + +/// Option to choose whether to track sentinels. +/// +/// This option affects the ABI for the nodes. When not specified explicitly, +/// sentinel tracking is disabled by default. Specify explicitly to +/// enable \a ilist_node::isSentinel(). +template struct ilist_sentinel_tracking +{ +}; + +/// Option to specify a tag for the node type. +/// +/// This option allows a single value type to be inserted in multiple lists +/// simultaneously. See \a ilist_node for usage examples. +template struct ilist_tag +{ +}; + +/// Option to add extra bits to the ilist_iterator. +/// +/// Some use-cases (debug-info) need to know whether a position is intended +/// to be half-open or fully open, i.e. whether to include any immediately +/// adjacent debug-info in an operation. This option adds two bits to the +/// iterator class to store that information. +template struct ilist_iterator_bits +{ +}; + +/// Option to add a pointer to this list's owner in every node. +/// +/// This option causes the \a ilist_base_node for this list to contain a pointer +/// ParentTy *Parent, returned by \a ilist_base_node::getNodeBaseParent() and +/// set by \a ilist_base_node::setNodeBaseParent(ParentTy *Parent). The parent +/// value is not set automatically; the ilist owner should set itself as the +/// parent of the list sentinel, and the parent should be set on each node +/// inserted into the list. This value is also not used by +/// \a ilist_node_with_parent::getNodeParent(), but is used by \a +/// ilist_iterator::getNodeParent(), which allows the parent to be fetched from +/// any valid (non-null) iterator to this list, including the sentinel. +template struct ilist_parent +{ +}; + +namespace ilist_detail +{ + +/// Helper trait for recording whether an option is specified explicitly. +template struct explicitness +{ + static const bool is_explicit = IsExplicit; +}; +using is_explicit = explicitness; +using is_implicit = explicitness; + +/// Check whether an option is valid. +/// +/// The steps for adding and enabling a new ilist option include: +/// \li define the option, ilist_foo, above; +/// \li add new parameters for Bar to \a ilist_detail::node_options; +/// \li add an extraction meta-function, ilist_detail::extract_foo; +/// \li call extract_foo from \a ilist_detail::compute_node_options and pass it +/// into \a ilist_detail::node_options; and +/// \li specialize \c is_valid_option> to inherit from \c +/// std::true_type to get static assertions passing in \a simple_ilist and \a +/// ilist_node. +template struct is_valid_option : std::false_type +{ +}; + +/// Extract sentinel tracking option. +/// +/// Look through \p Options for the \a ilist_sentinel_tracking option, with the +/// default disabled. +template struct extract_sentinel_tracking; +template +struct extract_sentinel_tracking< + ilist_sentinel_tracking, Options...> + : std::bool_constant, is_explicit +{ +}; +template +struct extract_sentinel_tracking + : extract_sentinel_tracking +{ +}; +template <> struct extract_sentinel_tracking<> : std::false_type, is_implicit +{ +}; +template +struct is_valid_option> + : std::true_type +{ +}; + +/// Extract custom tag option. +/// +/// Look through \p Options for the \a ilist_tag option, pulling out the +/// custom tag type, using void as a default. +template struct extract_tag; +template +struct extract_tag, Options...> +{ + using type = Tag; +}; +template +struct extract_tag : extract_tag +{ +}; +template <> struct extract_tag<> +{ + using type = void; +}; +template struct is_valid_option> : std::true_type +{ +}; + +/// Extract iterator bits option. +/// +/// Look through \p Options for the \a ilist_iterator_bits option. Defaults +/// to false. +template struct extract_iterator_bits; +template +struct extract_iterator_bits, Options...> + : std::bool_constant +{ +}; +template +struct extract_iterator_bits + : extract_iterator_bits +{ +}; +template <> struct extract_iterator_bits<> : std::false_type, is_implicit +{ +}; +template +struct is_valid_option> : std::true_type +{ +}; + +/// Extract node parent option. +/// +/// Look through \p Options for the \a ilist_parent option, pulling out the +/// custom parent type, using void as a default. +template struct extract_parent; +template +struct extract_parent, Options...> +{ + using type = ParentTy; +}; +template +struct extract_parent : extract_parent +{ +}; +template <> struct extract_parent<> +{ + using type = void; +}; +template +struct is_valid_option> : std::true_type +{ +}; + +/// Check whether options are valid. +/// +/// The conjunction of \a is_valid_option on each individual option. +template +struct check_options : std::conjunction...> +{ +}; + +/// Traits for options for \a ilist_node. +/// +/// This is usually computed via \a compute_node_options. +template +struct node_options +{ + using value_type = T; + using pointer = T *; + using reference = T &; + using const_pointer = const T *; + using const_reference = const T &; + + static const bool enable_sentinel_tracking = EnableSentinelTracking; + static const bool is_sentinel_tracking_explicit = IsSentinelTrackingExplicit; + static const bool has_iterator_bits = HasIteratorBits; + using tag = TagT; + using parent_ty = ParentTy; + using node_base_type = ilist_node_base; + using list_base_type = ilist_base; +}; + +template struct compute_node_options +{ + using type = node_options::value, + extract_sentinel_tracking::is_explicit, + typename extract_tag::type, + extract_iterator_bits::value, + typename extract_parent::type>; +}; + +} // end namespace ilist_detail +} // end namespace libbase + +#endif // LIBBASE_ADT_ILIST_NODE_OPTIONS_H -- cgit v1.2.3