double でテンプレートメタプログラミング

C++

double は非型テンプレートパラメータに使えないので,そのコンパイル時計算は constexpr 関数に頼るのが一般的だと思いますが,テンプレートでもやってやれないことはありません. // 有名な階乗の計算を double で行います // Gamma function ではありませ…

そろそろ result_of について

result_of とは 呼び出し可能な型と引数の型から,呼び出した場合の戻り値の型を導出するメタ関数です.例を示しましょう. typedef int (*char_to_int)(char); int digit_to_int(char c) { return c - '0'; } // char_to_int 型に,char 型の引数を渡した時…

PStade.Egg.Monad で遊んでみた

Undocumented ですが,pstade/egg/monad/ 以下に Monad クラスと boost::optional をそのインスタンスとしたものがあります.実用向きとは言えませんが,ちょっと遊んでみました. monad_optional_test.cpp #define BOOST_RESULT_OF_USE_DECLTYPE #include <cmath> </cmath>…

boost::array 型のメンバ変数を初期化子リストで初期化する

追記: 名前を変更 (elements → braced2).boost::array に限らず { { args... } } で初期化できるものなら大体使えます.また少し変更すれば { args... } などで初期化することもできます. C++03 では,配列型のメンバ変数を初期化子リストで初期化すること…

C++ で一般化された on を書く

Data.Function on :: (b -> b -> c) -> (a -> b) -> a -> a -> c on f g = \x y -> f (g x) (g y) これの引数の数と型を一般化したものを,C++ を使っていくつかの方法で書いてみました.Variadic な関数オブジェクトを書く上で参考になるかもしれません. …

文字列リテラルを型の世界へ!

C++

以下のようなことを可能にします。 string_test.cpp #include <iostream> #include "./string.hpp" template <class> struct print; template <char ...String> struct print<udon::string<String...>> { void operator()() const { char const s[] = { String..., 0 }; std::cout << s << std::endl; } }; int main() </udon::string<string...></char></class></iostream>…

std::tuple の Fusion アダプト

Sandbox にありました。Fusion を C++0x に移植する試みのようです (参照)。 https://svn.boost.org/svn/boost/sandbox/SOC/2009/fusion/自分でも書いてみました。GCC 4.5, GCC 4.6, VC10 に対応しています。 ヘッダ https://gist.github.com/996989 テスト …

Boost.Move 解説 (後編)

前回の続きです。今回は、Boost.Move による引数の転送を中心に解説していきたいと思います。 前回の補足 Boost.Move を使う利点 重要なことに触れていませんでした。 Move semantics は、乱暴に言えば「死すべきオブジェクト (rvalue) からは破壊的コピーを…

Boost.Move 解説 (前編)

はじめに Boost.Move は、C++0x で導入される move sematics を C++03 でエミュレートするべく、Ion Gaztanaga 氏 (Boost.Interprocess の作者) によって開発されたライブラリです。既に Boost 入りが決定しており、現在 trunk にあります。 この記事は、そ…

Boost.Move に対応した array

※ Boost.Move の入っている revision について書きます Boost.Interprocess には Boost.Move に対応したコンテナが付属していますが、その中に std::array に相当するものはありません。これは、move constructor などを追加することにより、array が aggreg…

C++0x で make_fused を書く

C++

Variadic Templates を使うことによって、驚くほど簡潔に書くことができます (Egg に合わせて fuse という名前にしています)。 #include <cstddef> #include <tuple> #include <type_traits> #include <utility> namespace fuse_detail { template <std::size_t ...Indexes> struct index_tuple { typedef index_tuple<Indexes..., sizeof...(Indexes)> next;</indexes...,></std::size_t></utility></type_traits></tuple></cstddef>…

関数適用演算子

Haskell には関数適用演算子 $ があり、しばしば括弧を省く目的で用いられます。C++ でもやってみましょう。 #include <utility> namespace apply { template <class F, class A> inline auto operator|=(F &&f, A &&a) -> decltype(std::forward<F>(f)(std::forward<A>(a))) { return std::fo</a></f></class></utility>…

C++03 で使える reference_wrapper

導入 C++0x の std::reference_wrapper は operator() を参照先に forward するので、関数オブジェクトを要求する関数 (STL アルゴリズムなど) にそのまま渡すことができます。 しかし、boost でこれに相当すると思われる boost::reference_wrapper にはこの…

range-based for マクロを書いてみた

C++

range-based for は案5に決まったらしいので、勉強がてらに自分で実装してみました。せっかくなので、VC10 でも動くようにしています。まずは使い方から。 int main() { // http://www.kmonos.net/alang/boost/classes/foreach.html int array[] = {1, 2, 3,…

C API の range ラッパー

以前少し考えたことがあったのですが、最近同じ話題を見かけたのでまとめてみました。 Range の要素がメモリの連続領域にあること (すなわち、&*(begin(r)+n)==&*begin(r)+n が常に成り立つこと) が保証されていれば、その range のデータをレガシーな C API…

type_traits を実装する (2)

C++

つい先日まで、is_constructible は SFINAE を使って以下のように実装できるものだと思っていました。 ※この記事では void や array of unknown bound は考慮しません。 template <class T, class ...Args> struct is_constructible { private: template <class U, class = int> struct test : std::false_t</class></class>…

Deleter を取る scoped_ptr

クラステンプレートの引数で deleter を取るものであれば、boost::interprocess::scoped_ptr があります。今回は、コンストラクタテンプレートの引数で deleter を取るものを C++0x で書いてみました。 GCC 4.6 で入った新機能 noexcept, nullptr も使ってい…

Immutable な片方向リスト

C++

書いてみました。GCC 4.5.2 以降 (-std=c++0x) 専用です。 https://gist.github.com/891955 標準の sequence container に似せてありますが、次の点で大きく異なります。 要素は変更できない insert, erase, clear などの操作を行うと、リスト自身は変更され…

foldr を書く

C++

foldr とは次のような関数です。 foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) これを C++ で書いてみます (foldr' を書きます)。 仕様は accumulate のものを copy and paste (+ modify) して以下のよ…

ネストされた range の入出力

実用には耐えませんが、ちょっとしたデバッグなどに。 入力をオウム返しする例 #include <deque> #include <iostream> #include <list> #include <vector> #include "./printed.hpp" #include "./scanned.hpp" int main() { std::deque<std::list<std::vector<int>>> rng; std::cin >> (rng | vitro::scanned); // >>> {</std::list<std::vector<int></vector></list></iostream></deque>…

split adaptor

リストの分割は 検索:デリミタを探す 分割:トークンのリストを作る(空のトークンを除去する、デリミタを残すなど) という2つの独立した操作に分解できると思ったので、2つの操作をポリシーでカスタマイズできるようなsplit iteratorを作り、それをベースに…

Boost.PPでクイックソート(改良版)

まず素直に再帰で実装したものがこちら。 http://ideone.com/3Sz2P 美しくありませんね。 マクロは再帰できないため、ループや再帰を実現するにはどこかでこのような連番マクロを使う必要があります。しかし、そういった汚れ仕事はBoost.PPのWHILEやSEQ_FOLD…

Boost.PPでエラトステネスの篩

プリプロセッサをやればかわいい妹ができると聞いて。 #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/arithmetic/mod.hpp> #include <boost/preprocessor/comparison/not_equal.hpp> #include <boost/preprocessor/repetition/for.hpp> #include <boost/preprocessor/seq/enum.hpp> #include </boost/preprocessor/seq/enum.hpp></boost/preprocessor/repetition/for.hpp></boost/preprocessor/comparison/not_equal.hpp></boost/preprocessor/arithmetic/mod.hpp></boost/preprocessor/arithmetic/inc.hpp>

多相ファンクタのはなし

関数テンプレートは型がないというお話がありました。値もありません。 template <class T> T square(T x) { return x * x; } int main() { int array[] = {0, 1, 2, 3}; std::vector<int> v; // エラー!squareを引数として使用できない std::transform(array, array + 4, </int></class>…

Rangeの直積を作るadaptor

直積を作るadaptorがない気がしたので書いてみました。 つかいかた #include <iostream> #include <string> #include <boost/lambda/lambda.hpp> #include <boost/range/algorithm/for_each.hpp> #include <boost/range/irange.hpp> #include <boost/tuple/tuple_io.hpp> #include "product.hpp" int main() { // (1 a) (1 b) (1 c) (2 a) (2 b) (2 c) …</boost/tuple/tuple_io.hpp></boost/range/irange.hpp></boost/range/algorithm/for_each.hpp></boost/lambda/lambda.hpp></string></iostream>

Rangeの内容を出力する

C++

こんな感じで使います。 int main() { using namespace std; vector<vector<string>> v{{"abc", "def"}, {"ghi", "jkl"}}; cout << iorate::print(v); } 出力 {{abc,def},{ghi,jkl}}実装 #include <iostream> #include <iterator> #include <type_traits> namespace iorate { template <class T> struct print_holder {</class></type_traits></iterator></iostream></vector<string>…

論理演算

C++

あると便利だと思うのですが、C++0xにはありません。 #include <type_traits> // and template <class ...Fs> struct and_ : std::true_type {}; template <class F1, class ...Fs> struct and_<F1, Fs...> : std::conditional<F1::value, and_<Fs...>, std::false_type>::type {}; // or template <class ...Fs> struct or_ : std::false_type {}…</class></f1::value,></f1,></class></class></type_traits>

を少し実装してみた

C++

C++0xのは型に関する情報を取得する重要なライブラリで、GCC4やVC10でも実装が提供されています。しかしそのうちのtype propertiesに関しては、N3225で大幅に変更されたこともあり、未実装の部分が多く残っています。 そこで、GCC4.6.0(20110122)を使い、未…

constexprなCRCを実装する

C++

switch case で文字列を使う - とくにあぶなくないRiSKのブログ ハッシュ関数としてCRC-CCITTを実装してみました。 #include <cstdint> #include <iostream> #include <string> namespace crc_ccitt { constexpr unsigned int process_char(unsigned int acc, int n) { return n > 0 ? p</string></iostream></cstdint>…

rangeをより小さな部分に分割するadaptor

rangeを一定サイズの部分rangeに分割するadaptorを書いてみました。こんな感じに使えます。 #include <iostream> #include <boost/lambda/lambda.hpp> #include <boost/range/algorithm/for_each.hpp> #include <boost/range/as_literal.hpp> #include "chunked.hpp" int main() { boost::for_each( // 文字列を4文字ごとに分割する boost::as_literal("Hello, wor</boost/range/as_literal.hpp></boost/range/algorithm/for_each.hpp></boost/lambda/lambda.hpp></iostream>…