1515
1616namespace llvm {
1717
18- template <bool EnableSentinelTracking> class ilist_node_base ;
19- template <bool EnableSentinelTracking> class ilist_base ;
18+ template <bool EnableSentinelTracking, class ParentPtrTy > class ilist_node_base ;
19+ template <bool EnableSentinelTracking, class ParentPtrTy > class ilist_base ;
2020
2121// / Option to choose whether to track sentinels.
2222// /
@@ -39,6 +39,19 @@ template <class Tag> struct ilist_tag {};
3939// / iterator class to store that information.
4040template <bool ExtraIteratorBits> struct ilist_iterator_bits {};
4141
42+ // / Option to add a pointer to this list's owner in every node.
43+ // /
44+ // / This option causes the \a ilist_base_node for this list to contain a pointer
45+ // / ParentTy *Parent, returned by \a ilist_base_node::getNodeBaseParent() and
46+ // / set by \a ilist_base_node::setNodeBaseParent(ParentTy *Parent). The parent
47+ // / value is not set automatically; the ilist owner should set itself as the
48+ // / parent of the list sentinel, and the parent should be set on each node
49+ // / inserted into the list. This value is also not used by
50+ // / \a ilist_node_with_parent::getNodeParent(), but is used by \a
51+ // / ilist_iterator::getNodeParent(), which allows the parent to be fetched from
52+ // / any valid (non-null) iterator to this list, including the sentinel.
53+ template <class ParentTy > struct ilist_parent {};
54+
4255namespace ilist_detail {
4356
4457// / Helper trait for recording whether an option is specified explicitly.
@@ -114,6 +127,21 @@ template <> struct extract_iterator_bits<> : std::false_type, is_implicit {};
114127template <bool IteratorBits>
115128struct is_valid_option <ilist_iterator_bits<IteratorBits>> : std::true_type {};
116129
130+ // / Extract node parent option.
131+ // /
132+ // / Look through \p Options for the \a ilist_parent option, pulling out the
133+ // / custom parent type, using void as a default.
134+ template <class ... Options> struct extract_parent ;
135+ template <class ParentTy , class ... Options>
136+ struct extract_parent <ilist_parent<ParentTy>, Options...> {
137+ typedef ParentTy *type;
138+ };
139+ template <class Option1 , class ... Options>
140+ struct extract_parent <Option1, Options...> : extract_parent<Options...> {};
141+ template <> struct extract_parent <> { typedef void type; };
142+ template <class ParentTy >
143+ struct is_valid_option <ilist_parent<ParentTy>> : std::true_type {};
144+
117145// / Check whether options are valid.
118146// /
119147// / The conjunction of \a is_valid_option on each individual option.
@@ -128,7 +156,7 @@ struct check_options<Option1, Options...>
128156// /
129157// / This is usually computed via \a compute_node_options.
130158template <class T , bool EnableSentinelTracking, bool IsSentinelTrackingExplicit,
131- class TagT , bool HasIteratorBits>
159+ class TagT , bool HasIteratorBits, class ParentPtrTy >
132160struct node_options {
133161 typedef T value_type;
134162 typedef T *pointer;
@@ -140,15 +168,18 @@ struct node_options {
140168 static const bool is_sentinel_tracking_explicit = IsSentinelTrackingExplicit;
141169 static const bool has_iterator_bits = HasIteratorBits;
142170 typedef TagT tag;
143- typedef ilist_node_base<enable_sentinel_tracking> node_base_type;
144- typedef ilist_base<enable_sentinel_tracking> list_base_type;
171+ typedef ParentPtrTy parent_ptr_ty;
172+ typedef ilist_node_base<enable_sentinel_tracking, parent_ptr_ty>
173+ node_base_type;
174+ typedef ilist_base<enable_sentinel_tracking, parent_ptr_ty> list_base_type;
145175};
146176
147177template <class T , class ... Options> struct compute_node_options {
148178 typedef node_options<T, extract_sentinel_tracking<Options...>::value,
149179 extract_sentinel_tracking<Options...>::is_explicit,
150180 typename extract_tag<Options...>::type,
151- extract_iterator_bits<Options...>::value>
181+ extract_iterator_bits<Options...>::value,
182+ typename extract_parent<Options...>::type>
152183 type;
153184};
154185
0 commit comments