介绍一下自己写的几个简单易用的工具包。
- 用到了部分 C++14 的特性(ISO C++14标准)。
- 吐槽一下:C++ 某些老东西为了兼容 C 弄得真是特别不好用。
- 工具源码:这里。
- 有空会继续更新。
Utils
m_cal_time.h
用来计算函数执行时间的工具,使用方法见下面的示例:
auto f1 = [](int i, int j, int k) -> std::vector<int>
{
std::vector<int> r(i * j * k);
size_t cnt = 0;
for (int x = 1; x <= i; ++x)
{
for (int y = 1; y <= j; ++y)
{
for (int z = 1; z <= k; ++z)
{
r[cnt++] = x * y * z;
}
}
}
return r;
};
auto f2 = [](int i, int j, int k) -> void
{
for (int x = 1; x <= i; ++x)
{
for (int y = 1; y <= j; ++y)
{
for (int z = 1; z <= k; ++z)
{
}
}
}
};
auto r1 = morisa::m_cal_time_with_return(f1, 100, 100, 100);
std::cout << "time: " << r1.time_ms << "ms\n";
std::cout << "r last: " << r1.data[r1.data.size() - 1] << "\n";
auto r2 = morisa::m_cal_time(f2, 100, 100, 100);
std::cout << "time: " << r2.time_ms << "ms\n";
执行结果:
time: 5ms r last: 1000000 time: 2ms
有返回值的函数可以用 m_cal_time
和 m_cal_time_with_return
,无返回值的函数只能用 m_cal_time
。
m_log.h
用来输出日志信息的工具,使用方法见下面的示例:
auto f = [](int x, int y) -> int
{
if (y == 0)
{
throw std::runtime_error("Zero can't be divisor.");
}
return x / y;
};
try
{
f(1, 0);
}
catch (std::runtime_error& e)
{
morisa::m_log(e.what());
}
morisa::m_log("morisa66\n", "game over");
日志记录:
Sat Mar 20 11:23:34 2021 Zero can't be divisor.
Sat Mar 20 11:23:34 2021 morisa66 game over
- 日志路径可以修改宏定义 LOG_PATH。
- 确保调用的是
m_log
而不是_m_log
。 - 支持线程锁。
m_shared_ptr.h
实现的简易共享指针,支持多线程安全,使用方法见下面的示例:
class Base
{
public:
virtual ~Base() {}
};
class A : public Base
{
public:
~A() { morisa::m_log("~A"); }
};
int main()
{
using morisa::m_shared_ptr;
using morisa::m_dynamic_cast;
using morisa::m_static_cast;
using morisa::m_log;
m_shared_ptr<A> p1(new A());
m_log("p1: ", p1.get_counter()); // p1: 1
m_shared_ptr<Base> p2;
m_log("p2: ", p2.get_counter()); // p2: 0
p2 = p1;
m_log("p2: ", p2.get_counter()); // p2: 2
m_shared_ptr<A> p3 = m_dynamic_cast<A>(p2);
m_log("p3: ", p3.get_counter()); // p3: 3
m_shared_ptr<Base> p4 = m_static_cast<Base>(p3);
m_log("p4: ", p4.get_counter()); // p4: 4
m_log("p1: ", p1.get_counter()); // p1: 4
p1.release();
m_log("p1: ", p1.get_counter()); // p1: 0
m_log("p4: ", p4.get_counter()); // p4: 3
return 0; // ~A
}
m_fun.h
复合函数 m_composite_fun
。
auto f1 = [](auto&& v)
{
return v + v;
};
auto f2 = [](auto&& v)
{
return v * v;
};
std::cout << morisa::m_composite_fun(f1, f2)(10); // f1(f2(10)) = 200
在编译期判断某个类是否有某个成员函数 m_has_xxx
。
struct Obj
{
void reserve(size_t i) {};
void emplace_back(Obj obj) {};
};
int main()
{
using type_v = std::vector<Obj>;
using std::cout;
cout << morisa::m_has_reserve<type_v>::value << "\n"; // true
cout << morisa::m_has_reserve<Obj>::value << "\n"; // true
cout << morisa::m_has_resize<type_v>::value << "\n"; // true
cout << morisa::m_has_resize<Obj>::value << "\n"; // false
cout << morisa::m_has_emplace_back<type_v, Obj>::value << "\n"; // true
cout << morisa::m_has_emplace_back<Obj, Obj>::value << "\n"; // true
return 0;
}
m_jthread.h
简单封装了一下 thread
(C++ 20会出来 jthread
)。
- 自动
join
。 - 支持移动构造和赋值。
使用方法见下面的示例:
std::mutex mtx01;
std::condition_variable cv;
bool ready = false;
void fun(int i)
{
std::unique_lock<std::mutex> lck(mtx01);
while (!ready)
{
cv.wait(lck);
}
morisa::m_log("thread", i);
}
void start()
{
std::unique_lock<std::mutex> lck(mtx01);
ready = true;
cv.notify_one(); // cv.notify_one()
}
int main()
{
using morisa::m_jthread;
const int N = 10;
m_jthread threads[N];
for (int i = 0; i < N; ++i)
{
threads[i] = m_jthread(fun, i);
}
start();
return 0;
}
日志里面会打印出 thread 0 ~ 9
If it is useful, and you would like to help me, please Money🤡Money🤡Money🤡!
- 本文链接:https://morisa66.github.io/2021/03/20/Utils/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。