No Such Blog or Diary

«Prev || 1 | 2 | 3 |...| 7 | 8 | 9 |...| 12 | 13 | 14 || Next»

OpenC++ Core

OpenC++ のパーサ部分(frontend)だけ欲しいと思っていたら丁度良く OpenC++Core なるものがあった.とりあえず普通にコンパイルできてテストのソースも読むことができてるので自前でパーサを作る必要が無くなって一安心.ただ,シェルスクリプトやテストの出力比較用ファイルが CR+LF の改行になっているのはいただけない… CVSから最新版を落とそうとしたらタイムアウトしたのも残念…

gcc2.95.2 をコンパイル

適当なバージョンの libstdc++ がほしいので gcc2.95.2 をコンパイル(ムダ).しかし, glibc-2.2 以降ではパッチを当てないとコンパイルできないことに気づかず時間を無駄に.

結局 ftp://ftp.ilog.fr/pub/Users/haible/utf8/gcc-glibc-2.2-compat.diff のパッチを当てなさいとのこと.それはさておき glibc のバージョンを下げないとやりたいことができないのかも…

Java to C#

Visual Studio .NET に Java から C# への変換機能があることを知ったので試してみた.結構機械的に置換できるからうまくいくだろうと思っていたら

//UPGRADE_TODO: コンストラクタ 'java.io.FileReader.FileReader' は、動作の異なる 'System.IO.StreamReader' に変換されました。

とかいわれて FileReader まわりがうまく変換されないらしい.ついでに複数個の Main があると怒られるのもどうにかしてほしいような... なんだかんだで結構面倒な気がする.

続・QRコード

ついでなのでQRコード生成プログラムに GUI をつけてみる(ソース(C#))..NET Framework 2.0 から FlowLayoutPanel と TableLayoutPanel が増えたので試してみたがどちらも微妙に使いきれず... TableLayoutPanel の下端がどっかにいってしまうのをどうにもできん.あと, NumericUpDown という数字を矢印ボタンで上下できるコントロールも使ってみたが,こちらは非常に使いやすかった(単純だし).とりあえず次は40型まで対応したデコーダがほしいので時間があったら作るとしよう.

QRコード

とりあえず「QRコードは(株)デンソーウェーブの登録商標です」 と書いておく.

壁にかかっていたポスター見たらQRコードが入っていたので,おもむろに生成プログラムを自分で組んでみた.規格自体は JIS X0510 でオープンなのでオンライン閲覧で誤植を発見しつつゴリゴリと.勉強のため C# で組んだはいいが全然 C# らしく無いコードだったりするけど.(ソース(C#))(仕様書からパラメータを拾うのが一番面倒で大変だった...).んで,できたのがこれらで,携帯使うと確かに読み取れる.

    QRcode_ls-al.jp.pngQRcode_ls-al.jp_big.png
アドレスのみ
(2-Q (Size: 25x25), Mode: BYTE)
    アドレス+α
(8-Q (Size: 49x49), Mode: BYTE)

プログラムは最大の40型(177x177)まで対応してるけどこのサイズを読めるリーダが無く確認できない... どうでもよいが手元の携帯の限界は15型(77x77)らしい. 最後に,このLICENSEを40型(37型で足りるけど)でやってみる.

LICENSE_QRv40.png

サブクラス判定

ちゃんと探せば STL や Boost に is_convertible と is_base とかがあった.肝を抜き出してみるとこんなもん.

#include <iostream>
using namespace std;
 
template<typename From, typename To>
struct isConvertible {
    static char test(To);
    static long test(...); // variable argument で逃げる
    static From from();
    static const bool value = sizeof(test(from())) == 1;
};
 
class A {};
class B : public A {};
 
int main(int argc, char *argv[])
{
    cout << isConvertible<A, B>::value << endl;
    cout << isConvertible<B, A>::value << endl;
    return 0;
}

test 関数の呼び出しで From から To に変換できる場合は test(To) が選択され,sizeof(test(from())) = 1 となるので value = true となる.そうでなければ test(...) が選択され sizeof(test(from())) != 1 で value = false と.variable arguments 使って型指定をなくせるのに気づかなかった...

もう少し高度なトリックを使うと次の is_base のメイン部分になるらしい.

#include <iostream>
using namespace std;
 
template <typename Super, typename Sub>
struct isSuperclasOf {
    template<typename T>
    static char test(Sub &, T);    
    static long test(Super &, int);
    struct C {
        operator Super &() const;
        operator Sub &();
    };
    static const bool value = sizeof(test(C(), 0)) == 1;
};
 
class A {};
class B : public A {};
 
int main(int argc, char *argv[])
{
    cout << isSuperclasOf<A, B>::value << endl;
    cout << isSuperclasOf<B, A>::value << endl;
    return 0;
}

http://tinyurl.com/502fhttp://tinyurl.com/6jvyq に原理が書いてある.結局はある変換系列が他の変換系列の prefix になっているなら短い型変換が優先で,テンプレート有り関数とテンプレート無し関数では無い関数が優先であることを使っているらしい.Super が Sub の親クラスの場合,test(Super&, int) が呼ばれるには C → Sub → Super の変換列をとり( C → C const → Super 側は無視される),一方で test(Sub&, int) は C → Sub という変換列となる.このとき, C → Sub が C → Sub → Super の prefix になっているので test(Sub&, int) が選択される.よって,sizeof(test(C(), 0)) が 1 になるので value が true になる.Super が Sub の親クラスで無い場合は,test(Super&, int) が呼ばれるには C → C const → Super という変換列となり,これは C → Sub に吸収されないので test(Super&, int) と test(Sub&, int) の可能性がある.しかし,test(Sub&, int) に関してはテンプレートの instantiation があるので test(Super&, int) が選択される.よって,この場合は sizeof(test(C(), 0)) が 1 でないので value が false になる.

よくかんがえるもんだなぁ.

«Prev || 1 | 2 | 3 |...| 7 | 8 | 9 |...| 12 | 13 | 14 || Next»
Search
Feeds

Page Top