Vecの実装 in Rust - Deref

前回 に引き続き、 The RustnomiconImplementing Vec をやってみる。

コード全体は GitHub上のリポジトリ にある。

rustcのバージョンは以下のとおり。

$ rustc --version
rustc 1.25.0-nightly (27a046e93 2018-02-18)

Deref

標準ライブラリのドキュメント を見ると、 Vec に適用できるかなりのメソッドはスライスへのderef.を経由して呼べることが分かる。 Vec の中身は同じ型を集めた配列なので、スライスへderef.するのは自然である。

そこで、Deref<Target = [T]> for Vec<T> を実装する。 簡単で、slice::from_raw_parts() を呼ぶだけである。 はじめのアドレスと要素数を渡すとスライスを作ってくれる。 要素数が0のときも正しく動作するようだ。

use std::ops::Deref;

impl<T> Deref for Vec<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe { ::std::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
    }
}

&mut [T] にderef.する DerefMut 版もつくっておく。 今度は slice::from_raw_parts_mut() を呼ぶ。 DerefMut: Deref なので、Target の指定は必要ない。

use std::ops::{Deref, DerefMut};

impl<T> DerefMut for Vec<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe { ::std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
    }
}