Older/ToolKit/Util/List.h

219 lines
4.3 KiB
C
Raw Normal View History

2024-09-28 23:55:00 +08:00
/*
* Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
*
* This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLTOOLKIT_LIST_H
#define ZLTOOLKIT_LIST_H
#include <list>
#include <type_traits>
namespace toolkit {
#if 0
template<typename T>
class List;
template<typename T>
class ListNode
{
public:
friend class List<T>;
~ListNode(){}
template <class... Args>
ListNode(Args&&... args):_data(std::forward<Args>(args)...){}
private:
T _data;
ListNode *next = nullptr;
};
template<typename T>
class List {
public:
using NodeType = ListNode<T>;
List(){}
List(List &&that){
swap(that);
}
~List(){
clear();
}
void clear(){
auto ptr = _front;
auto last = ptr;
while(ptr){
last = ptr;
ptr = ptr->next;
delete last;
}
_size = 0;
_front = nullptr;
_back = nullptr;
}
template<typename FUN>
void for_each(FUN &&fun) const {
auto ptr = _front;
while (ptr) {
fun(ptr->_data);
ptr = ptr->next;
}
}
size_t size() const{
return _size;
}
bool empty() const{
return _size == 0;
}
template <class... Args>
void emplace_front(Args&&... args){
NodeType *node = new NodeType(std::forward<Args>(args)...);
if(!_front){
_front = node;
_back = node;
_size = 1;
}else{
node->next = _front;
_front = node;
++_size;
}
}
template <class...Args>
void emplace_back(Args&&... args){
NodeType *node = new NodeType(std::forward<Args>(args)...);
if(!_back){
_back = node;
_front = node;
_size = 1;
}else{
_back->next = node;
_back = node;
++_size;
}
}
T &front() const{
return _front->_data;
}
T &back() const{
return _back->_data;
}
T &operator[](size_t pos){
NodeType *front = _front ;
while(pos--){
front = front->next;
}
return front->_data;
}
void pop_front(){
if(!_front){
return;
}
auto ptr = _front;
_front = _front->next;
delete ptr;
if(!_front){
_back = nullptr;
}
--_size;
}
void swap(List &other){
NodeType *tmp_node;
tmp_node = _front;
_front = other._front;
other._front = tmp_node;
tmp_node = _back;
_back = other._back;
other._back = tmp_node;
size_t tmp_size = _size;
_size = other._size;
other._size = tmp_size;
}
void append(List<T> &other){
if(other.empty()){
return;
}
if(_back){
_back->next = other._front;
_back = other._back;
}else{
_front = other._front;
_back = other._back;
}
_size += other._size;
other._front = other._back = nullptr;
other._size = 0;
}
List &operator=(const List &that) {
that.for_each([&](const T &t) {
emplace_back(t);
});
return *this;
}
private:
NodeType *_front = nullptr;
NodeType *_back = nullptr;
size_t _size = 0;
};
#else
template<typename T>
class List : public std::list<T> {
public:
template<typename ... ARGS>
List(ARGS &&...args) : std::list<T>(std::forward<ARGS>(args)...) {};
~List() = default;
void append(List<T> &other) {
if (other.empty()) {
return;
}
this->insert(this->end(), other.begin(), other.end());
other.clear();
}
template<typename FUNC>
void for_each(FUNC &&func) {
for (auto &t : *this) {
func(t);
}
}
template<typename FUNC>
void for_each(FUNC &&func) const {
for (auto &t : *this) {
func(t);
}
}
};
#endif
} /* namespace toolkit */
#endif //ZLTOOLKIT_LIST_H