From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- third_party/wasm2c/src/intrusive-list.h | 633 ++++++++++++++++++++++++++++++++ 1 file changed, 633 insertions(+) create mode 100644 third_party/wasm2c/src/intrusive-list.h (limited to 'third_party/wasm2c/src/intrusive-list.h') diff --git a/third_party/wasm2c/src/intrusive-list.h b/third_party/wasm2c/src/intrusive-list.h new file mode 100644 index 0000000000..7d9611a74a --- /dev/null +++ b/third_party/wasm2c/src/intrusive-list.h @@ -0,0 +1,633 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_INTRUSIVE_LIST_H_ +#define WABT_INTRUSIVE_LIST_H_ + +#include +#include +#include + +#include "src/make-unique.h" + +// This uses a similar interface as std::list, but is missing the following +// features: +// +// * Add "extract_" functions that remove an element from the list and return +// it. +// * Only supports move-only operations +// * No allocator support +// * No initializer lists +// * Asserts instead of exceptions +// * Some functions are not implemented (merge, remove, remove_if, reverse, +// unique, sort, non-member comparison operators) + +namespace wabt { + +template +class intrusive_list; + +template +class intrusive_list_base { + private: + friend class intrusive_list; + + mutable T* next_ = nullptr; + mutable T* prev_ = nullptr; +}; + +template +class intrusive_list { + public: + // types: + typedef T value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + class iterator; + class const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + // construct/copy/destroy: + intrusive_list(); + explicit intrusive_list(std::unique_ptr node); + explicit intrusive_list(T&& node); + intrusive_list(const intrusive_list&) = delete; + intrusive_list(intrusive_list&&); + ~intrusive_list(); + intrusive_list& operator=(const intrusive_list& other) = delete; + intrusive_list& operator=(intrusive_list&& other); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + size_type size() const noexcept; + bool empty() const noexcept; + + // element access: + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + // modifiers: + template + void emplace_front(Args&&... args); + template + void emplace_back(Args&&... args); + void push_front(std::unique_ptr node); + void push_front(T&& node); + void push_back(std::unique_ptr node); + void push_back(T&& node); + void pop_front(); + void pop_back(); + std::unique_ptr extract_front(); + std::unique_ptr extract_back(); + + template + iterator emplace(iterator pos, Args&&... args); + iterator insert(iterator pos, std::unique_ptr node); + iterator insert(iterator pos, T&& node); + std::unique_ptr extract(iterator it); + + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + void swap(intrusive_list&); + void clear() noexcept; + + void splice(iterator pos, intrusive_list& node); + void splice(iterator pos, intrusive_list&& node); + void splice(iterator pos, intrusive_list& node, iterator it); + void splice(iterator pos, + intrusive_list& node, + iterator first, + iterator last); + + private: + T* first_ = nullptr; + T* last_ = nullptr; + size_t size_ = 0; +}; + +/// iterator +template +class intrusive_list::iterator { + public: + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + + iterator(const intrusive_list& list, T* node) + : list_(&list), node_(node) {} + + reference operator*() const { + assert(node_); + return *node_; + } + + pointer operator->() const { + assert(node_); + return node_; + } + + iterator& operator++() { + assert(node_); + node_ = node_->next_; + return *this; + } + + iterator operator++(int) { + iterator tmp = *this; + operator++(); + return tmp; + } + + iterator& operator--() { + node_ = node_ ? node_->prev_ : list_->last_; + return *this; + } + + iterator operator--(int) { + iterator tmp = *this; + operator--(); + return tmp; + } + + bool operator==(iterator rhs) const { + assert(list_ == rhs.list_); + return node_ == rhs.node_; + } + + bool operator!=(iterator rhs) const { + assert(list_ == rhs.list_); + return node_ != rhs.node_; + } + + private: + friend class const_iterator; + + const intrusive_list* list_; + T* node_; +}; + +/// const_iterator +template +class intrusive_list::const_iterator { + public: + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef const T* pointer; + typedef const T& reference; + + const_iterator(const intrusive_list& list, T* node) + : list_(&list), node_(node) {} + + const_iterator(const iterator& other) + : list_(other.list_), node_(other.node_) {} + + reference operator*() const { + assert(node_); + return *node_; + } + + pointer operator->() const { + assert(node_); + return node_; + } + + const_iterator& operator++() { + assert(node_); + node_ = node_->next_; + return *this; + } + + const_iterator operator++(int) { + const_iterator tmp = *this; + operator++(); + return tmp; + } + + const_iterator& operator--() { + node_ = node_ ? node_->prev_ : list_->last_; + return *this; + } + + const_iterator operator--(int) { + const_iterator tmp = *this; + operator--(); + return tmp; + } + + bool operator==(const_iterator rhs) const { + assert(list_ == rhs.list_); + return node_ == rhs.node_; + } + + bool operator!=(const_iterator rhs) const { + assert(list_ == rhs.list_); + return node_ != rhs.node_; + } + + private: + const intrusive_list* list_; + T* node_; +}; + +template +inline intrusive_list::intrusive_list() {} + +template +inline intrusive_list::intrusive_list(std::unique_ptr node) { + push_back(std::move(node)); +} + +template +inline intrusive_list::intrusive_list(T&& node) { + push_back(std::move(node)); +} + +template +inline intrusive_list::intrusive_list(intrusive_list&& other) + : first_(other.first_), last_(other.last_), size_(other.size_) { + other.first_ = other.last_ = nullptr; + other.size_ = 0; +} + +template +inline intrusive_list::~intrusive_list() { + clear(); +} + +template +inline intrusive_list& intrusive_list::operator=( + intrusive_list&& other) { + clear(); + first_ = other.first_; + last_ = other.last_; + size_ = other.size_; + other.first_ = other.last_ = nullptr; + other.size_ = 0; + return *this; +} + +template +inline typename intrusive_list::iterator +intrusive_list::begin() noexcept { + return iterator(*this, first_); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::begin() + const noexcept { + return const_iterator(*this, first_); +} + +template +inline typename intrusive_list::iterator intrusive_list::end() noexcept { + return iterator(*this, nullptr); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::end() const + noexcept { + return const_iterator(*this, nullptr); +} + +template +inline typename intrusive_list::reverse_iterator +intrusive_list::rbegin() noexcept { + return reverse_iterator(iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::rbegin() const noexcept { + return const_reverse_iterator(const_iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::reverse_iterator +intrusive_list::rend() noexcept { + return reverse_iterator(iterator(*this, first_)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::rend() const noexcept { + return const_reverse_iterator(const_iterator(*this, first_)); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::cbegin() + const noexcept { + return const_iterator(*this, first_); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::cend() + const noexcept { + return const_iterator(*this, nullptr); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::crbegin() const noexcept { + return const_reverse_iterator(const_iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::crend() const noexcept { + return const_reverse_iterator(const_iterator(*this, first_)); +} + +template +inline typename intrusive_list::size_type intrusive_list::size() const + noexcept { + return size_; +} + +template +inline bool intrusive_list::empty() const noexcept { + return size_ == 0; +} + +template +inline typename intrusive_list::reference intrusive_list::front() { + assert(!empty()); + return *first_; +} + +template +inline typename intrusive_list::const_reference intrusive_list::front() + const { + assert(!empty()); + return *first_; +} + +template +inline typename intrusive_list::reference intrusive_list::back() { + assert(!empty()); + return *last_; +} + +template +inline typename intrusive_list::const_reference intrusive_list::back() + const { + assert(!empty()); + return *last_; +} + +template +template +inline void intrusive_list::emplace_front(Args&&... args) { + push_front(MakeUnique(std::forward(args)...)); +} + +template +template +inline void intrusive_list::emplace_back(Args&&... args) { + push_back(MakeUnique(std::forward(args)...)); +} + +template +inline void intrusive_list::push_front(std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p = node.release(); + if (first_) { + node_p->next_ = first_; + first_->prev_ = node_p; + } else { + last_ = node_p; + } + first_ = node_p; + size_++; +} + +template +inline void intrusive_list::push_front(T&& node) { + push_front(MakeUnique(std::move(node))); +} + +template +inline void intrusive_list::push_back(std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p = node.release(); + if (last_) { + node_p->prev_ = last_; + last_->next_ = node_p; + } else { + first_ = node_p; + } + last_ = node_p; + size_++; +} + +template +inline void intrusive_list::push_back(T&& node) { + push_back(MakeUnique(std::move(node))); +} + +template +inline void intrusive_list::pop_front() { + extract_front(); +} + +template +inline void intrusive_list::pop_back() { + extract_back(); +} + +template +inline std::unique_ptr intrusive_list::extract_front() { + assert(!empty()); + T* node = first_; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + first_ = first_->next_; + first_->prev_ = nullptr; + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +inline std::unique_ptr intrusive_list::extract_back() { + assert(!empty()); + T* node = last_; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + last_ = last_->prev_; + last_->next_ = nullptr; + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +template +inline typename intrusive_list::iterator intrusive_list::emplace( + iterator pos, + Args&&... args) { + return insert(pos, MakeUnique(std::forward(args)...)); +} + +template +inline typename intrusive_list::iterator intrusive_list::insert( + iterator pos, + std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p; + if (pos == end()) { + push_back(std::move(node)); + node_p = &back(); + } else { + node_p = node.release(); + node_p->prev_ = pos->prev_; + node_p->next_ = &*pos; + if (pos->prev_) { + pos->prev_->next_ = node_p; + } else { + first_ = node_p; + } + pos->prev_ = node_p; + size_++; + } + return iterator(*this, node_p); +} + +template +inline typename intrusive_list::iterator intrusive_list::insert( + iterator pos, + T&& node) { + return insert(pos, MakeUnique(std::move(node))); +} + +template +inline std::unique_ptr intrusive_list::extract(iterator pos) { + assert(!empty()); + assert(pos != end()); + T* node = &*pos; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + if (node->prev_) { + node->prev_->next_ = node->next_; + } else { + first_ = node->next_; + } + + if (node->next_) { + node->next_->prev_ = node->prev_; + } else { + last_ = node->prev_; + } + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +inline typename intrusive_list::iterator intrusive_list::erase( + iterator pos) { + iterator next = std::next(pos); + extract(pos); + return next; +} + +template +inline typename intrusive_list::iterator intrusive_list::erase( + iterator first, + iterator last) { + while (first != last) + first = erase(first); + return first; +} + +template +inline void intrusive_list::swap(intrusive_list& other) { + std::swap(first_, other.first_); + std::swap(last_, other.last_); + std::swap(size_, other.size_); +} + +template +inline void intrusive_list::clear() noexcept { + for (T* iter = first_; iter;) { + T* next = iter->next_; + delete iter; + iter = next; + } + first_ = last_ = nullptr; + size_ = 0; +} + +template +inline void intrusive_list::splice(iterator pos, intrusive_list& other) { + splice(pos, other, other.begin(), other.end()); +} + +template +inline void intrusive_list::splice(iterator pos, intrusive_list&& other) { + splice(pos, other, other.begin(), other.end()); +} + +template +inline void intrusive_list::splice(iterator pos, + intrusive_list& other, + iterator it) { + insert(pos, other.extract(it)); +} + +template +inline void intrusive_list::splice(iterator pos, + intrusive_list& other, + iterator first, + iterator last) { + while (first != last) + insert(pos, other.extract(first++)); +} + +} // namespace wabt + +#endif // WABT_INTRUSIVE_LIST_H_ -- cgit v1.2.3