aboutsummaryrefslogtreecommitdiff
path: root/pw_containers/public/pw_containers/internal/intrusive_list_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'pw_containers/public/pw_containers/internal/intrusive_list_impl.h')
-rw-r--r--pw_containers/public/pw_containers/internal/intrusive_list_impl.h82
1 files changed, 74 insertions, 8 deletions
diff --git a/pw_containers/public/pw_containers/internal/intrusive_list_impl.h b/pw_containers/public/pw_containers/internal/intrusive_list_impl.h
index c77a2ca66..c10ff1d88 100644
--- a/pw_containers/public/pw_containers/internal/intrusive_list_impl.h
+++ b/pw_containers/public/pw_containers/internal/intrusive_list_impl.h
@@ -78,26 +78,69 @@ class Iterator {
class List {
public:
class Item {
+ public:
+ /// Items are not copyable.
+ Item(const Item&) = delete;
+
+ /// Items are not copyable.
+ Item& operator=(const Item&) = delete;
+
protected:
+ /// Default constructor.
+ ///
+ /// All other constructors must call this to preserve the invariant that an
+ /// item is always part of a cycle.
constexpr Item() : Item(this) {}
+ /// Destructor.
+ ///
+ /// This is O(n), where "n" is the number of items in this object's list.
~Item() { unlist(); }
+ /// Move constructor.
+ ///
+ /// This uses the move assignment operator. See the note on that method.
+ ///
+ /// This should NOT typically be used, except for testing.
+ Item(Item&& other);
+
+ /// Move assignment operators.
+ ///
+ /// This will unlist the current object, and replace other with this object
+ /// in the list that contained it. As a result, this O(m + n), where "m" is
+ /// the number of items in this object's list, and "n" is the number of
+ /// objects in the `other` object's list.
+ ///
+ /// As such, it should NOT typically be used, except for testing.
+ Item& operator=(Item&& other);
+
+ /// Returns whether this object is not part of a list.
+ ///
+ /// This is O(1) whether the object is in a list or not.
+ bool unlisted() const { return this == next_; }
+
+ /// Unlink this from the list it is apart of, if any.
+ ///
+ /// Specifying prev saves calling previous(), which requires looping around
+ /// the cycle. This is O(1) with `previous`, and O(n) without.
+ void unlist(Item* prev = nullptr);
+
private:
friend class List;
template <typename T, typename I>
friend class Iterator;
- constexpr Item(Item* next) : next_(next) {}
-
- bool unlisted() const { return this == next_; }
-
- // Unlink this from the list it is apart of, if any. Specifying prev saves
- // calling previous(), which requires looping around the cycle.
- void unlist(Item* prev = nullptr);
+ /// Explicit constructor.
+ ///
+ /// In addition to the default constructor for Item, this is used by the
+ /// default constructor for List to create its sentinel value.
+ explicit constexpr Item(Item* next) : next_(next) {}
- Item* previous(); // Note: O(n) since it loops around the cycle.
+ /// Return the previous item in the list by looping around the cycle.
+ ///
+ /// This is O(n), where "n" is the number of items in this object's list.
+ Item* previous();
// The next pointer. Unlisted items must be self-cycles (next_ == this).
Item* next_;
@@ -122,28 +165,51 @@ class List {
bool empty() const noexcept { return begin() == end(); }
+ /// Inserts an item into a list.
+ ///
+ /// The item given by `pos` is updated to point to the item as being next in
+ /// the list, while the item itself points to what `pos` previously pointed to
+ /// as next.
+ ///
+ /// This is O(1). The ownership of the item is not changed.
static void insert_after(Item* pos, Item& item);
+ /// Removes an item from a list.
+ ///
+ /// The item that `pos` points to as being next in the list is unlisted, while
+ /// `pos` is updated to point to the item following it as next.
+ ///
+ /// This is O(1). The item is not destroyed..
static void erase_after(Item* pos);
void clear();
bool remove(const Item& item_to_remove);
+ /// Returns a pointer to the sentinel item.
constexpr Item* before_begin() noexcept { return &head_; }
constexpr const Item* before_begin() const noexcept { return &head_; }
+ /// Returns a pointer to the first item.
constexpr Item* begin() noexcept { return head_.next_; }
constexpr const Item* begin() const noexcept { return head_.next_; }
+ /// Returns a pointer to the last item.
Item* before_end() noexcept;
+ /// Returns a pointer to the sentinel item.
constexpr Item* end() noexcept { return &head_; }
constexpr const Item* end() const noexcept { return &head_; }
+ /// Returns the number of items in the list by looping around the cycle.
+ ///
+ /// This is O(n), where "n" is the number of items in the list.
size_t size() const;
private:
+ /// Adds items to the list from the provided range.
+ ///
+ /// This is O(n), where "n" is the number of items in the range.
template <typename Iterator>
void AssignFromIterator(Iterator first, Iterator last);