mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-09 13:41:47 +00:00
ADT: Split out iplist_impl from iplist, NFC
Split out iplist_impl from iplist, and change SymbolTableList to inherit directly from iplist_impl. This makes it more straightforward to add new template paramaters to iplist [*]: - iplist_impl takes a "base" list that provides the intrusive functionality (usually simple_ilist<T>) and a traits class. - iplist no longer takes a "Traits" template parameter. It only takes the value_type, T, and instantiates iplist_impl with simple_ilist<T> and ilist_traits<T>. - SymbolTableList now inherits from iplist_impl, instead of iplist. Note for out-of-tree code: if you have an iplist whose second template parameter was *not* the default (i.e., not ilist_traits<YourT>), you have three options: - Stop using a custom traits class, and instead specialize ilist_traits<YourT>. This is the usual thing to do. - Specialize iplist<YourT> to pass your custom traits class into iplist_impl. - Create your own trivial list type that passes your custom traits class into iplist_impl (see SymbolTableList<> for an example). [*]: The eventual goal is to start tracking a sentinel bit on the MachineInstr list even when LLVM_ENABLE_ABI_BREAKING_CHECKS is off, which will enable MachineBasicBlock::reverse_iterator to have normal list invalidation semantics that matching the new iplist<>::reverse_iterator from r280032. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0bb0baeec0
commit
fe32eccfec
@ -145,14 +145,21 @@ template <class TraitsT, class NodeT> struct HasObsoleteCustomization {
|
|||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
/// The subset of list functionality that can safely be used on nodes of
|
/// A wrapper around an intrusive list with callbacks and non-intrusive
|
||||||
|
/// ownership.
|
||||||
|
///
|
||||||
|
/// This wraps a purely intrusive list (like simple_ilist) with a configurable
|
||||||
|
/// traits class. The traits can implement callbacks and customize the
|
||||||
|
/// ownership semantics.
|
||||||
|
///
|
||||||
|
/// This is a subset of ilist functionality that can safely be used on nodes of
|
||||||
/// polymorphic types, i.e. a heterogeneous list with a common base class that
|
/// polymorphic types, i.e. a heterogeneous list with a common base class that
|
||||||
/// holds the next/prev pointers. The only state of the list itself is an
|
/// holds the next/prev pointers. The only state of the list itself is an
|
||||||
/// ilist_sentinel, which holds pointers to the first and last nodes in the
|
/// ilist_sentinel, which holds pointers to the first and last nodes in the
|
||||||
/// list.
|
/// list.
|
||||||
template <class T, class Traits = ilist_traits<T>>
|
template <class IntrusiveListT, class TraitsT>
|
||||||
class iplist : public Traits, simple_ilist<T> {
|
class iplist_impl : public TraitsT, IntrusiveListT {
|
||||||
typedef simple_ilist<T> base_list_type;
|
typedef IntrusiveListT base_list_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename base_list_type::pointer pointer;
|
typedef typename base_list_type::pointer pointer;
|
||||||
@ -172,19 +179,20 @@ private:
|
|||||||
// TODO: Drop this assertion and the transitive type traits anytime after
|
// TODO: Drop this assertion and the transitive type traits anytime after
|
||||||
// v4.0 is branched (i.e,. keep them for one release to help out-of-tree code
|
// v4.0 is branched (i.e,. keep them for one release to help out-of-tree code
|
||||||
// update).
|
// update).
|
||||||
static_assert(!ilist_detail::HasObsoleteCustomization<Traits, value_type>::value,
|
static_assert(
|
||||||
"ilist customization points have changed!");
|
!ilist_detail::HasObsoleteCustomization<TraitsT, value_type>::value,
|
||||||
|
"ilist customization points have changed!");
|
||||||
|
|
||||||
static bool op_less(const_reference L, const_reference R) { return L < R; }
|
static bool op_less(const_reference L, const_reference R) { return L < R; }
|
||||||
static bool op_equal(const_reference L, const_reference R) { return L == R; }
|
static bool op_equal(const_reference L, const_reference R) { return L == R; }
|
||||||
|
|
||||||
// Copying intrusively linked nodes doesn't make sense.
|
// Copying intrusively linked nodes doesn't make sense.
|
||||||
iplist(const iplist &) = delete;
|
iplist_impl(const iplist_impl &) = delete;
|
||||||
void operator=(const iplist &) = delete;
|
void operator=(const iplist_impl &) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iplist() = default;
|
iplist_impl() = default;
|
||||||
~iplist() { clear(); }
|
~iplist_impl() { clear(); }
|
||||||
|
|
||||||
// Miscellaneous inspection routines.
|
// Miscellaneous inspection routines.
|
||||||
size_type max_size() const { return size_type(-1); }
|
size_type max_size() const { return size_type(-1); }
|
||||||
@ -197,7 +205,7 @@ public:
|
|||||||
using base_list_type::front;
|
using base_list_type::front;
|
||||||
using base_list_type::back;
|
using base_list_type::back;
|
||||||
|
|
||||||
void swap(iplist &RHS) {
|
void swap(iplist_impl &RHS) {
|
||||||
assert(0 && "Swap does not use list traits callback correctly yet!");
|
assert(0 && "Swap does not use list traits callback correctly yet!");
|
||||||
base_list_type::swap(RHS);
|
base_list_type::swap(RHS);
|
||||||
}
|
}
|
||||||
@ -253,7 +261,7 @@ private:
|
|||||||
// transfer - The heart of the splice function. Move linked list nodes from
|
// transfer - The heart of the splice function. Move linked list nodes from
|
||||||
// [first, last) into position.
|
// [first, last) into position.
|
||||||
//
|
//
|
||||||
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
|
void transfer(iterator position, iplist_impl &L2, iterator first, iterator last) {
|
||||||
if (position == last)
|
if (position == last)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -297,33 +305,33 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Splice members - defined in terms of transfer...
|
// Splice members - defined in terms of transfer...
|
||||||
void splice(iterator where, iplist &L2) {
|
void splice(iterator where, iplist_impl &L2) {
|
||||||
if (!L2.empty())
|
if (!L2.empty())
|
||||||
transfer(where, L2, L2.begin(), L2.end());
|
transfer(where, L2, L2.begin(), L2.end());
|
||||||
}
|
}
|
||||||
void splice(iterator where, iplist &L2, iterator first) {
|
void splice(iterator where, iplist_impl &L2, iterator first) {
|
||||||
iterator last = first; ++last;
|
iterator last = first; ++last;
|
||||||
if (where == first || where == last) return; // No change
|
if (where == first || where == last) return; // No change
|
||||||
transfer(where, L2, first, last);
|
transfer(where, L2, first, last);
|
||||||
}
|
}
|
||||||
void splice(iterator where, iplist &L2, iterator first, iterator last) {
|
void splice(iterator where, iplist_impl &L2, iterator first, iterator last) {
|
||||||
if (first != last) transfer(where, L2, first, last);
|
if (first != last) transfer(where, L2, first, last);
|
||||||
}
|
}
|
||||||
void splice(iterator where, iplist &L2, reference N) {
|
void splice(iterator where, iplist_impl &L2, reference N) {
|
||||||
splice(where, L2, iterator(N));
|
splice(where, L2, iterator(N));
|
||||||
}
|
}
|
||||||
void splice(iterator where, iplist &L2, pointer N) {
|
void splice(iterator where, iplist_impl &L2, pointer N) {
|
||||||
splice(where, L2, iterator(N));
|
splice(where, L2, iterator(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Compare>
|
template <class Compare>
|
||||||
void merge(iplist &Right, Compare comp) {
|
void merge(iplist_impl &Right, Compare comp) {
|
||||||
if (this == &Right)
|
if (this == &Right)
|
||||||
return;
|
return;
|
||||||
this->transferNodesFromList(Right, Right.begin(), Right.end());
|
this->transferNodesFromList(Right, Right.begin(), Right.end());
|
||||||
base_list_type::merge(Right, comp);
|
base_list_type::merge(Right, comp);
|
||||||
}
|
}
|
||||||
void merge(iplist &Right) { return merge(Right, op_less); }
|
void merge(iplist_impl &Right) { return merge(Right, op_less); }
|
||||||
|
|
||||||
using base_list_type::sort;
|
using base_list_type::sort;
|
||||||
|
|
||||||
@ -352,6 +360,13 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// An intrusive list with ownership and callbacks specified/controlled by
|
||||||
|
/// ilist_traits, only with API safe for polymorphic types.
|
||||||
|
template <class T>
|
||||||
|
class iplist : public iplist_impl<simple_ilist<T>, ilist_traits<T>> {};
|
||||||
|
|
||||||
|
/// An intrusive list with ownership and callbacks specified/controlled by
|
||||||
|
/// ilist_traits, with API that is unsafe for polymorphic types.
|
||||||
template <class T> class ilist : public iplist<T> {
|
template <class T> class ilist : public iplist<T> {
|
||||||
typedef iplist<T> base_list_type;
|
typedef iplist<T> base_list_type;
|
||||||
|
|
||||||
|
@ -105,8 +105,9 @@ public:
|
|||||||
/// When nodes are inserted into and removed from this list, the associated
|
/// When nodes are inserted into and removed from this list, the associated
|
||||||
/// symbol table will be automatically updated. Similarly, parent links get
|
/// symbol table will be automatically updated. Similarly, parent links get
|
||||||
/// updated automatically.
|
/// updated automatically.
|
||||||
template <typename NodeTy>
|
template <class T>
|
||||||
class SymbolTableList : public iplist<NodeTy, SymbolTableListTraits<NodeTy>> {};
|
class SymbolTableList
|
||||||
|
: public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user