提交 1d028c6a 编写于 作者: Y yang li 提交者: youngwolf

Use std::forward_list instead of std::list, and implement size concept like...

Use std::forward_list instead of std::list, and implement size concept like boost::container::slist does.
上级 391f81bc
......@@ -169,3 +169,122 @@ int main(int argc, const char* argv[])
return 0;
}
/*
#include <ascs/list.h>
using namespace ascs;
void print_list(const list<int>& l)
{
if (!l.empty())
{
for (auto& item : l)
printf("%d ", item);
printf(": %d %Iu\n", l.back(), l.size());
}
else
printf("empty list: %Iu\n", l.size());
}
void test1()
{
list<int> l;
l.push_back(0);
l.push_back(1);
l.push_back(2);
print_list(l);
list<int> l2;
l2.push_back(10);
l2.push_back(11);
l2.push_back(12);
print_list(l2);
l.splice_after(l2);
print_list(l);
print_list(l2);
}
void test2()
{
list<int> l;
l.push_back(0);
l.push_back(1);
l.push_back(2);
print_list(l);
list<int> l2;
l2.push_back(10);
l2.push_back(11);
l2.push_back(12);
print_list(l2);
l.splice_after_until(l2, std::begin(l2));
print_list(l);
print_list(l2);
}
void test3()
{
list<int> l;
l.push_back(0);
l.push_back(1);
l.push_back(2);
print_list(l);
list<int> l2;
l2.push_back(10);
l2.push_back(11);
l2.push_back(12);
print_list(l2);
auto iter = std::begin(l2);
l.splice_after_until(l2, ++iter);
print_list(l);
print_list(l2);
}
void test4()
{
list<int> l;
l.push_back(0);
l.push_back(1);
l.push_back(2);
print_list(l);
list<int> l2;
l2.push_back(10);
l2.push_back(11);
l2.push_back(12);
print_list(l2);
l.splice_after_until(l2, std::end(l2));
print_list(l);
print_list(l2);
}
void test5()
{
list<int> l, l2;
l2.push_back(10);
l2.push_back(11);
l2.push_back(12);
print_list(l2);
l.splice_after_until(l2, std::end(l2));
print_list(l);
print_list(l2);
}
int main(int argc, const char* argv[])
{
typedef void (*TEST_FUN) ();
TEST_FUN tests[] = {&test1, &test2, &test3, &test4, &test5};
for (size_t i = 0; i < sizeof(tests) / sizeof(TEST_FUN); ++i)
{
(*tests[i])();
puts("");
}
return 0;
}
*/
......@@ -16,7 +16,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <list>
#include <mutex>
#include <vector>
#include <chrono>
......@@ -35,6 +34,7 @@
#include <asio.hpp>
#include "config.h"
#include "list.h"
namespace ascs
{
......@@ -159,9 +159,6 @@ protected:
buffer_type buffer;
};
//ascs requires that container must take one and only one template argument
template<typename T> using list = std::list<T>;
//packer concept
template<typename MsgType>
class i_packer
......
......@@ -43,15 +43,15 @@ private:
std::mutex mutex; //std::mutex is more efficient than std::shared_(timed_)mutex
};
//Container must at least has the following functions (like std::list):
//Container must at least has the following functions (like std::forward_list):
// Container() and Container(size_t) constructor
// empty, must be thread safe, but doesn't have to be consistent
// clear
// swap
// template<typename T> emplace_back(const T& item), if you call direct_(sync_)send_msg which accepts other than rvalue reference
// template<typename T> emplace_back(T&& item)
// splice(iter, Container&)
// splice(iter, Container&, iter, iter)
// splice_after(Container&)
// splice_after_until(Container&, iter)
// front
// pop_front
// back
......@@ -117,7 +117,7 @@ public:
else
assert(ascs::get_size_in_byte(src) == size_in_byte);
this->splice(this->end(), src);
this->splice_after(src);
total_size += size_in_byte;
}
......@@ -127,7 +127,7 @@ public:
{
if ((size_t) -1 == max_item_num)
{
dest.splice(std::end(dest), *this);
dest.splice_after(*this);
total_size = 0;
}
else if (max_item_num > 0)
......@@ -173,9 +173,9 @@ protected:
#endif
{
if (end_iter == this->end())
dest.splice(std::end(dest), *this);
dest.splice_after(*this);
else
dest.splice(std::end(dest), *this, this->begin(), end_iter);
dest.splice_after_until(*this, end_iter);
total_size -= size;
}
......
......@@ -13,6 +13,8 @@
#ifndef _ASCS_EXT_H_
#define _ASCS_EXT_H_
#include <list>
#include "../base.h"
//the size of the buffer used when receiving msg, must equal to or larger than the biggest msg size,
......
......@@ -125,7 +125,7 @@ public:
auto head_len = packer_helper::pack_header(len);
out.emplace_back((const char*) &head_len, ASCS_HEAD_LEN);
out.splice(std::end(out), in);
out.splice_after(in);
return true;
}
......@@ -193,7 +193,7 @@ public:
auto raw_msg = new string_buffer();
raw_msg->assign((const char*) &head_len, ASCS_HEAD_LEN);
out.emplace_back(raw_msg);
out.splice(std::end(out), in);
out.splice_after(in);
return true;
}
......@@ -293,7 +293,7 @@ public:
if (!_prefix.empty())
out.emplace_back(_prefix);
out.splice(std::end(out), in);
out.splice_after(in);
if (!_suffix.empty())
out.emplace_back(_suffix);
......
/*
* base.h
*
* Created on: 2019-4-18
* Author: youngwolf
* email: mail2tao@163.com
* QQ: 676218192
* Community on QQ: 198941541
*
* forward list, but has size, push_back and emplace_back functions.
*/
#ifndef _ASCS_LIST_H_
#define _ASCS_LIST_H_
#include <forward_list>
namespace ascs
{
//ascs requires that container must take one and only one template argument
template<typename T>
class list : protected std::forward_list<T>
{
private:
typedef std::forward_list<T> super;
public:
using typename super::value_type;
using typename super::size_type;
using typename super::reference;
using typename super::const_reference;
using typename super::iterator;
using typename super::const_iterator;
using super::empty;
using super::max_size;
using super::begin;
using super::cbegin;
using super::front;
using super::end;
using super::cend;
public:
list() {refresh_status();}
list(size_type count) : super(count) {refresh_status();}
list(super&& other) {swap(other);}
list(const super& other) {*this = other;}
list(list&& other) {refresh_status(); swap(other);}
list(const list& other) {*this = other;}
list& operator=(super&& other) {super::clear(); swap(other); return *this;}
list& operator=(const super& other) {super::operator=(other); refresh_status(); return *this;}
list& operator=(list&& other) {clear(); swap(other); return *this;}
list& operator=(const list& other) {super::operator=(other); refresh_status(); return *this;}
void swap(super& other) {super::swap(other); refresh_status();}
void swap(list& other) {super::swap(other); std::swap(s, other.s); std::swap(back_iter, other.back_iter);}
void refresh_status()
{
s = 0;
back_iter = this->before_begin();
for (auto iter = std::begin(*this); iter != std::end(*this); ++iter, ++back_iter)
++s;
}
void clear() {super::clear(); refresh_status();}
size_type size() const {return s;}
void push_front(T&& _Val) {super::push_front(std::forward<T>(_Val)); if (1 == ++s) back_iter = std::begin(*this);}
template<class... _Valty> void emplace_front(_Valty&&... _Val) {super::emplace_front(std::forward<_Valty>(_Val)...); if (1 == ++s) back_iter = std::begin(*this);}
void pop_front() {super::pop_front(); if (0 == --s) back_iter = std::end(*this);}
void push_back(T&& _Val) {back_iter = this->insert_after(1 == ++s ? this->cbefore_begin() : back_iter, std::forward<T>(_Val));}
template<class... _Valty> void emplace_back(_Valty&& ... _Val) {back_iter = this->emplace_after(1 == ++s ? this->cbefore_begin() : back_iter, std::forward<_Valty>(_Val)...);}
reference back() {return *back_iter;}
const_reference back() const {return *back_iter;}
void splice_after(super& other)
{
if (!other.empty())
{
super::splice_after(empty() ? this->cbefore_begin() : back_iter, other);
refresh_status();
}
}
#ifdef _MSC_VER
void splice_after(list& other) {splice_after((super&) other); other.refresh_status();}
#else
void splice_after(list& other)
{
if (!other.empty())
{
s += other.s;
super::splice_after(empty() ? this->cbefore_begin() : back_iter, other);
back_iter = other.back_iter;
other.refresh_status();
}
}
#endif
void splice_after_until(super& other, const_iterator last) {super::splice_after(empty() ? this->cbefore_begin() : back_iter, other, other.cbefore_begin(), last); refresh_status();}
void splice_after_until(list& other, const_iterator last) {splice_after_until((super&) other, last); other.refresh_status();}
private:
size_type s;
iterator back_iter; //for empty list, this item can be either before_begin() or end(), please note.
};
} //namespace
#endif /* _ASCS_LIST_H_ */
......@@ -246,7 +246,7 @@ public:
sr_status = sync_recv_status::REQUESTED;
auto re = sync_recv_waiting(lock, duration);
if (sync_call_result::SUCCESS == re)
msg_can.splice(std::end(msg_can), temp_msg_can);
msg_can.splice_after(temp_msg_can);
sr_status = sync_recv_status::NOT_REQUESTED;
sync_recv_cv.notify_one();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册