2013-08-01から1ヶ月間の記事一覧

対数オーダーでTemplate Parameter Packから要素を取り出す

一巡先を見る為にライブラリ始めました。 怜-toki- C++ Template Meta Programming Library https://github.com/fimbul/toki ライブラリ自体に需要があるかは分かりませんが、基本的にプリプロセッサ無しで型コンテナやらメタ関数やらTMPやるときに役立ちそ…

渡された型のtemplate parametersを得るメタ関数2

先日の件を経てcv修飾に対応しました。 もっと賢い実装がありそうですが、constとvolatileならせいぜい2 * 2通りしかないので凝ったことせずにそのままSFINAEで対応。 #include <iostream> #include <typeinfo> #include <cxxabi.h> #include <type_traits> #include <boost/mpl/vector.hpp> template<class... Types> struct Foo; template<class T> str</class></class...></boost/mpl/vector.hpp></type_traits></cxxabi.h></typeinfo></iostream>…

std::is_sameとmpl::equal

結論 Twitterで何人かの方に教えていただきました。 typeidがトップレベルのcv修飾や参照を無視するので、それをデマングルするとその部分だけが違う型は同じように表示されていました。 template<template<class...> class Type, class... Args> static const boost::mpl::vect</template<class...>…

渡された型のtemplate parametersを得るメタ関数

以前から渡された型のtemplate parametersを得るメタ関数が欲しいなと思っていて気が乗ったので書きました。 結果はその後扱いやすいようにboost::mpl::vectorにして返す事にしました。 tp_type<Type>::typeであればboost::mpl::vector<Type>を tp_type<Type<Types...>>::typeであればbo</type<types...></type></type>…

TMPの条件分岐に条件演算子が使えても良い気がする

以下のコードはgccでインスタンス化が無限再帰するコードです。 ちなみにclangでは無限再帰しないのではなく、エラーメッセージすら表示出来ずにPLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:を表示してクラッシュします。(まだバグ報告はしていま…

コンパイル時/実行時両用アサートについて考える

SPROUT_ASSERTは非常に優れており、コンパイル時、実行時両方で使えます。 しかし、以下のようなコードはコンパイルエラーにはならず、実行時に初めてアサーションに失敗します。 constexpr auto i = 0; SPROUT_ASSERT(i == 1); 一方、static_assertを用いる…

ラムダよくわからない

ラムダの挙動は難しいです。 コピーキャプチャされた要素の型に関してはdecltypeを用いた具体例による説明が規格内にありました。 void f3() { float x, &r = x; // x and r are not captured (appearance in a decltype operand is not an odr-use) [=] { d…

C++でクロージャを作る2

コピーなどにコストがかかってパフォーマンスも然程良くないので使い道が微妙ですが、クラスもどきです。 こういうのはやはり参照で寿命管理が上手く扱える、ガベージコレクタありきの技術ですね、基本的にC++には向かないです。 メンバ変数の宣言と初期化は…

clangにbug reportを出した

Bug 16907 - Crash in lambda expression http://llvm.org/bugs/show_bug.cgi?id=16907 C++でクロージャを作る(先程加筆修正しました) のコードを書いている時に、clangがクラッシュするコードを見つけたので本日報告しました。 以下のコードを実行するとcla…

C++でクロージャを作る

C++でもJavascriptなどと同様にクロージャを作る事が出来ます。 環境(状態)を持った関数オブジェクトといった感じで、分かっている人にとってはなんてことはないと思います。 ポイントはlambdaをコピーキャプチャとした上でmutableにすることです。 構造体や…

コンパイル時に配列の任意の箇所へ要素を挿入する

コンパイル時に配列の任意の箇所へ要素を挿入し、その結果を新しい配列として返す関数です。 push_at(array, value, position); によってarrayの中のpositionにvalueを挿入した配列を返します。 同様のテクニックを用いて、配列のある位置に別の配列の要素を…

コンパイル時に文字列を結合する

コンパイル時に使える文字列型のようなものを用意します。 2つの文字列を受け取る際に、templateでその文字列長を推論して得られるようにしておき、あとはindex_tuple idiomを用いて結合処理をして新しい文字列型を返します。 このようにすれば、副作用を用…

コンパイル時toupperとtolower

見たまんまですね。 文字列リテラル又はsprout::stringから処理を施したsprout::stringを生成します。 C++1yならdecltypeの部分は無くても動きますが、C++11対応のため。 #include <type_traits> #include <sprout/string.hpp> #include <sprout/index_tuple.hpp> template<class T, std::size_t size, sprout::index_t... indexes> constexpr auto toupper_impl(const T (&str</class></sprout/index_tuple.hpp></sprout/string.hpp></type_traits>…

bug reportのその後

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58091 However current ICC agrees with GCC. We may have something in Bugzilla. Generally speaking, this is a basic C++ issue, doesn't have to do with the recent constexpr, and normally icc is very…

gccにbug reportを出した

先日の以下の要素の参照は曖昧かについて、Twitterで江添さんからおそらくgccのバグではないかとの意見を頂いた(参考記事 : おそらくgccのバグ)のでgccにbug reportを出しておきました。 記事の解釈が正しければ、暫くしたらgccでも参照出来るように修正され…

Boost.PPでFizzBuzzし、コンパイル時に逆FizzBuzzで結果を検証する

Twitterで話題にしたので実装しました。 プリプロセッサでFizzBuzzの実装に結構苦労しましたがslotを駆使してなんとかなりました。 プリプロセッサでの再帰をslot(変数として働く)の利用と自分自身のincludeを使うことで実現しています。 #ifndef INIT #defi…

以下の要素の参照は曖昧か

#include <type_traits> namespace test { template<int... args> struct test { static constexpr auto value = 1; }; } int main() { using namespace test; static_assert(test<1>::value == 1, ""); // test<1>::valueはambiguous? } あるnamespace内に同名のtemplate structが存在</int...></type_traits>…

コンパイル時 逆fizzbuzz [C++]

巷で噂の逆fizzbuzz問題です。 http://d.hatena.ne.jp/matarillo/20120515/p1 コンパイル時に解けるようにテンプレート引数として<fizz,buzz,fizz,fizz...>といった物を与えるとfizzbuzzにおいてそれを生成する最小の数列を要素として持つsprout::array型のオブジェクトを得るメタ関</fizz,buzz,fizz,fizz...>…