見出し画像

猫娘曰く。0606-サクラのソート

はおはお。

先日、サクラエディタのソートの振る舞いを変更したんです。

これですね。

オリジナルのほうでは厳格に a-zA-Zの比較をしているためにフォルダとかリストアップしたときに「ソートされてない感」がすごいんですよね。

実際、オリジナルのほうでは

inline int CNativeW_comp(const CNativeW& lhs, const CNativeW& rhs )
{
	// 比較長には終端NULを含めないといけない
	return wmemcmp(lhs.GetStringPtr(), rhs.GetStringPtr(),
			t_min(lhs.GetStringLength() + 1, rhs.GetStringLength() + 1));
}

と振り分けていて wmemcmp関数を使用しています。これだと大文字小文字とか関係ないので混ざって並ぶことはありません。

とりあえず ここを変更でっす。

inline int CNativeW_comp(const CNativeW& lhs, const CNativeW& rhs )
{
	// 比較長には終端NULを含めないといけない
	return _memicmp(lhs.GetStringPtr(), rhs.GetStringPtr(),
	                t_min(lhs.GetStringLength() + 1, rhs.GetStringLength() + 1));
}

ここでは _memicmp関数を使用してみます。i付なので大文字小文字は区別しないで比較することが可能です。

ひとまずは期待した結果を出力することができましたけども、他の部分で必ずしも同じ結果になるとは限りませんので まだまだお試し中。ちゃんと別関数で定義しなさいよって言われちゃいますし、ソート方法の選択もできないと機能自体が変わっちゃうのでケアが必要です。

ついでに

CNativeW::GetStringLength()
関数は中で除算しているのでこれも何とかしたいところですね~。
(速度的に問題ないとかそういう話じゃなくて 比較関数内で除算を使いたくないってことね)

wchar_t operator[](int nIndex) const;                    //!< 任意位置の文字取得。nIndexは文字単位。
CLogicInt GetStringLength() const                        //!< 文字列長を返す。文字単位。
{
	return CLogicInt(CNative::GetRawLength() / sizeof(wchar_t));
}

2.4系ではどうなってるのかなー。コンパイラがいい感じに何とかしてくれるのかなー。ソートの方法にもよるけどキャッシュも少しは活用されてるだろうし……

ちなみにサクッとみてみた感じ ANSI版は

; 115  : 	return CNative::GetRawLength() / sizeof(char);

	mov	eax, DWORD PTR [rcx+16]

最適化されちゃってますネ。 / sizeof(char) がなかったことにされてるようで。Wide版ですが、

; 93   : 		return CLogicInt(CNative::GetRawLength() / sizeof(wchar_t));

	movsxd	rax, DWORD PTR [rcx+16]
	shr	rax, 1

やっぱシフトしてたw
movsxdが気になりますね。

さらについでに

これから かなカナの区別なしソートの実装もしてみようと思ってます。ソートの厳格レベルとしては……

  • 大文字小文字を区別する

  • かなカナを区別する

  • 日本語たちは無視される

さらにさらについでに

日本語もいいソートほしいじゃん~って思うので読みもソートの対象にしてみようと思っています。ここまでくると もう自己満足っぽいw


そんなことを考えていたりします。

悉く書を信ずれば則ち書無きに如かず