一周杂记 in Week 3 Mar 2022

感觉这周时间过得特别快。

Life

  • 周六去医院打了最后一针狂犬疫苗,只要疫苗是真的有效,那么至少 1-2 年内可以放肆撸猫(这个时间范围听医生说的)。
    有意思的是,这一次75块钱的针剂费依然走了医保,所以只能理解为大部分轮转医生搞不清楚疫苗不进入医保咯?

Read More

一周杂记 in Week 2 Mar 2022

Life

  • 这周各地都在冒疫情的病例,不知道是好消息还是坏消息。不过看趋势大概率清明应该没法回温州了
  • 抽个时间补了 The Thing 正传;正传的节奏和BGM都肉眼可见的比后来的前传要好

Read More

一周杂记 in Week 1 Mar 2022

Life

  • 这周沉迷 The Witcher S02,一周时间就把第二季刷完了。
    作为没玩过游戏的受众,人物选角没有让我有太强的违和感,没办法,Henry Cavill 的 Geralt 太香了,一人撑起全剧。当然,Yennefer 要是 Evan Green 来演我觉得更赞。 期待后续剧集

Read More

一周杂记 in Week 4 Feb 2022

Life

  • 刷完了 The Expanse S05;这一季主要仍是在做剧情铺垫和完善角色形象,但是这已经是倒数第二季了,这个时候才开始要丰满主要反派 Marco Inaros 的形象未免也太晚了吧。何况还要顺带加上 Philip…这就导致这一季又重复了一遍之前的旧模式,缺乏点新意。
    另外这一季 Alex 的演员因为性骚扰丑闻被剧本杀了,Clarissa 加入队伍,不得不感慨一下。
    同时 Mrs.Avasarala 重新当选为联合国秘书长;以及 White Collar 里的 Peter 叔 Tim DeKay 打了个酱油,出演反叛的 MCRN 军官,结果最后一集在穿越 Ring 的时候直接被湮灭了…

Read More

一周杂记 in Week 3 Feb 2022

节后第二周,生活和工作节奏都慢慢恢复到了之前的状态。

Life

  1. 一口气刷了好几集 The Expanse S05,感觉 S05 前半部分又在攒局积攒冲突。但是一个不好的地方是核心冲突又回到了人上,protomolecule 还是“飘在外面”;期待后续有更高的格局

Read More

一周杂记 in Week 2 Feb 2022

Blog 从上次更新到现在至少荒几个月。一直没更新主要是太懒了并且没有想到有什么需要特别写的。

春节休假期间偶尔反思了一下觉得还是需要日常回顾自省一下,就算没有什么新的体会或者收获,当 journal 留着万一哪天得了阿兹海默症没准还能起到正向作用 🤪。

Life

因为节前几天杭州出现了不大不小的疫情,出现扩散后老婆医院不允许医护回家所以又一起在杭州过了一次年。所以节后就没有请年,开始恢复工作节奏。

Read More

unique_ptr For Generic Scoped Handle

之前在 用 unique_ptr 管理 Windows HANDLE 中介绍了如何基于 std::unique_ptr 快速实现对 Windows HANDLE 的 RAII 化。

但是如果我们也要对 fd 或者 Windows 上的 SOCKET 做类似的处理,重复实现 xx_handlexx_handle_deleter 就显得过于琐碎。

实际上我们可以利用模板参数注入,将共同点抽象出来,不同点实现成各自的 type traits,然后利用模板进行注入。

这样一来,我们只需要简单实现每个 handle type 对应的基础属性,就可以直接复用核心实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
template<typename Traits>
class handle_ptr {
public:
using handle_type = typename Traits::handle_type;

handle_ptr() noexcept = default;

// implicit
handle_ptr(std::nullptr_t) noexcept {}

// implicit
handle_ptr(handle_type handle) noexcept
: handle_(handle) {}

~handle_ptr() = default;

explicit operator bool() const noexcept {
return Traits::is_valid(handle_);
}

// implicit
operator handle_type() const noexcept {
return handle_;
}

friend bool operator==(handle_ptr lhs, handle_ptr rhs) noexcept {
return lhs.handle_ == rhs.handle_;
}

friend bool operator!=(handle_ptr lhs, handle_ptr rhs) noexcept {
return !(lhs == rhs);
}

private:
handle_type handle_{Traits::null_handle};
};

template<typename Traits>
struct handle_ptr_deleter {
using pointer = handle_ptr<Traits>;

void operator()(pointer ptr) {
Traits::close(ptr);
}
};

PS:不同于文章中的例子,基底类起名 handle_ptr 更为确切;因为在 unique_ptr 的内部会用来定义 pointer;而几乎 unique_ptr 的语义行为都是围绕 pointer 来完成的。

有了上面这个基底之后,针对 fd-wrapper,我们只需要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct fd_traits {
using handle_type = int;

static bool is_valid(handle_type handle) noexcept {
return handle != null_handle;
}

static void close(handle_type handle) noexcept {
::close(handle);
}

static constexpr handle_type null_handle{-1};
};

using fd_deleter = handle_ptr_deleter<fd_traits>;
using unique_fd = std::unique_ptr<fd_traits::handle_type, fd_deleter>;

inline unique_fd wrap_unique_fd(int raw_fd) {
return unique_fd(raw_fd);
}

这样一来,实现一个新的 unique handle wrapper,我们只需要确定四个东西:

  1. handle type 的实际类型
  2. null handle 的值,用来确定 default/zero initialized 之后 handle 状态
  3. 实现 is_valid()
  4. 实现 close()

剩下的就是常规的类型实例化。

Read More