はじめに
突然ですが皆さんは好きなクラスはありますか?私はList<T>が好きです。
そっけない名前のくせにしっかりタイプセーフな所が魅力です。
そんなList<T>をC言語でも使えるようにしたいという気持ちが溢れ出しそうになったので、C言語でList<T>っぽいものを実装してみました。
作ったもの
といっても、List<T>の全てのメソッドを実装するのはしんどいです。
しんどいので今回はIList<T>で定義されているインターフェースだけ実装しました。
ソースコードは下記を参照ください。
https://github.com/nendo-code/CSList
CSList.hがIList<T>を実装したものになります。
CSList.hを使ってみる
CSList.hを使って下記のコードをC言語で実装してみます。
C#版コード
ListMain.cs
using System.Collections.Generic;
public class ListMain{
public static void Main(){
IList<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
foreach(int item in list){
System.Console.WriteLine(item);
}
}
}
C言語版コード
ListMain.c
#include "CSList.h"
#include <stdio.h>
CSList_use(int)
int main(int argc, char const *argv[]){
CSList(int) list = CSList_new(int);
list->Add(list,1);
list->Add(list,2);
list->Add(list,3);
CSList_foreach(int,item,list){
printf("%d\n",*item);
}CSList_foreach_end
CSList_delete(list);
return 0;
}
あまり違和感無くC言語でもList<T>っぽい実装ができているかと思います。
IList<T>で定義している程度のメソッドは実装されていますので、詳しく使い方を知りたい方はexample.cを参考にしてみてください。
組み込みなどPC以外の環境で使う場合はCSList_conf.hで環境に合わせた設定に書き換えて使って下さい。
感想
今回作ったCSListはC言語でジェネリックを実現するためにマクロを多用して実装しているのですが、黒魔術感が半端なく、デバッグがやや面倒でした。
が、頑張ったおかげでいちおうタイプセーフ(型の指定が違うとコンパイラがワーニングを吐くよ)なリストが出来たので満足しました。