C++

Generic Lambdas で has_xxx を実装する

C++

has_xxx とは型 x にネストされた名前 name があるかどうか調べるメタ関数の総称です。名前空間またはクラスのスコープでクラステンプレート has_name を定義し、その上で has_name<x>::value などとして使います。 本の虫: C++11におけるモダンなhas_xxxの実装</x>…

Boost.Asioでio_service::run()を包含する設計

C++

Boost.Asio io_serviceを包含する設計 - Faith and Brave - C++で遊ぼう 上の話に加えて、io_service::run()を誰が呼ぶかという話についてのメモ。 1つは上で紹介されているように、io_serviceを公開し、ユーザーにrun()させるパターン。 class client { pub…

Boost.Asioで非同期操作中に*thisの寿命が尽きることを防ぐ

C++

Boost.Asioを使って非同期操作を書いていると、メンバ関数から起動した非同期操作の最中に*thisの寿命が尽きて困ることがあります。 例えば次のHTTPクライアント: class http_client { public: // ... void start() { // ... // 名前解決を開始する m_resolv…

C++/Boostでオブジェクトへのアクセスを同期する方法メモ

C++

C++で、複数のスレッドから1つのオブジェクトにアクセスするときに同期をとる方法いろいろ。 1. atomicを使う 使える型は限られるが、お手軽。 std::atomic<int> x(0); boost::thread_group threads; for (int i = 0; i < 4; ++i) { threads.create_thread([&] { </int>…

タグ付きバリアント型(代数的データ型)

タグ付きタプル型 - yohhoyの日記 タグ付きバリアント型があってもいいじゃない。 Boost.Variant では要素の型で要素にアクセスしますが、代わりにタグ経由でアクセスすることで、 要素の意味が明確になる。 複数の同じ型の要素に別の意味を与えることができ…

HaskellのIntegerをC++で使う

C++の標準には多倍長整数ライブラリがありません。これは大変なことだと思います。 まあBoost.Multiprecision来るじゃないというのはさておき、 標準の多倍長整数がないなら他言語の標準から持ってくればいいということで、HaskellのIntegerをラップしてC++…

C++/Boost 小ネタ

コードだけ貼って全く説明しないのもアレかと思うので、汎用性のある手法をいくつか抜き出してみました。 boost::thread_specific_ptr Boost 版 TLS (Thread Local Storage)。thread_local がサポートされていない、でも __declspec(thread) や __thread は…

Boost.Context による単純なファイバー

いわゆる非対称コルーチン。C++03/11 両対応。 https://gist.github.com/3684731 簡単な使い方。 #include <iorate/fiber.hpp> int main() { iorate::fiber f([] { for (auto const c : "Hello, world!\n") { std::cout << c; iorate::fiber::yield(); } }); while (f.alive())</iorate/fiber.hpp>…

可変長引数を扱う手段として Fusion を使う

Variadic Template による可変長引数 ...args は f(args)... で f(a1), ..., f(aN) に展開できますが template <class ...Args> void fg(Args ...args) { f(g(args)...); // f(g(a1), ..., g(aN)) } 少し込み入ったことをする場合は、引数を Boost.Fusion の列にまとめてか</class>…

Boost.Context でジェネレータを作る

知らないうちに Boost.Context が trunk 入りしていたので,それを使って Python のジェネレータのようなものを作る CRTP クラスを書いてみました. generator.hpp メンバ関数 generate を実装するとジェネレータを作り上げてくれます.ジェネレータは,遅延…

ラムダ式でムーブキャプチャ

C++

ラムダ式での変数のキャプチャはコピーまたは参照で行いますが,ムーブするための標準的な方法はありません. std::unique_ptr<int> p(new int(23)); auto f = [std::move(p)] { std::cout << *p << '\n'; }; // こんな書き方はない どうしても変数 p をムーブし</int>…

Boost.Phoenix で range-based for

phx::for_each より楽に使えるものをと. https://gist.github.com/1540409 void revival_example() { using boost::phoenix::arg_names::_1; using boost::phoenix::arg_names::_2; using boost::phoenix::local_names::_x; int array[5] = { 1, 2, 3, 4, 5…

std::common_type の問題点

C++

SFINAE に使えない http://d.hatena.ne.jp/gintenlabo/20110420/1303288950 メタプログラミングをする上で不便ですね. 必ずしも「引数の型全てが変換される型」を返すとは限らない struct A { A(int) {} template <class T> A(T) = delete; }; char c = '$'; std::co</class>…

Range を使おう

C++

これは C++11 Advent Calendar 2011 の参加記事 (15日目) です. この記事では「Iterator ではなく Range を使おう」という話をします.既に何度も言われている話ではありますが,私も一度書いてみたかったのでこの機会に書きます.でもそんなに新しいことは…

Egg の楽しみ

これは Boost Advent Calendar 2011 の参加記事 (11 日目)です. 今日はせっかくの機会なので,個人的に関心の高い Egg について,ちょっと書いてみたいと思います.Egg を知らない人も多いと思いますので,ここでは入門・解説を書くのではなく,どのような…

何が lvalue で何が rvalue なのか

C++

こういう記事も必要かもしれないと思いました.内容はタイトルそのままです. はじめに はじめに,と書きましたがこの項は飛ばしても問題ないです. まず "lvalue" とか "rvalue" とかいうものが何についての概念なのかということですが,これらは C++ の "…

構造体を tuple-like としてアダプトするマクロを書いた

C++

C++11 の規格には,tuple-like という言葉が登場します.これは所謂コンセプトで,tuple-like コンセプトを満たす型 T は,std::tuple_size<T>,std::tuple_element<I, T>,get<I>(t) を持ちます.標準で定義されたものでは,std::pair<T1, T2>,std::tuple<Types...>,std::array<T, N> がこれを</t,></types...></t1,></i></i,></t>…

random_shuffled range アダプタ

久しぶりに range アダプタでも. 考え方は oven::sorted と同じで,range からイテレータのリストを作り,そのリストをシャッフルします.結果として forward range にも対応できます. random_shuffled.hpp (要 P-Stade) #ifndef IORATE_RANDOM_SHUFFLED_H…

constexpr の再帰上限数

C++

512 回以上であることが推奨されています.GCC 4.6.1 ではデフォルトで 512 回です. repeated.cpp // apply f n times to x template <class F, class T> constexpr T repeated(F f, unsigned n, T x) { return n == 0 ? x : repeated(f, n - 1, f(x)); } constexpr int inc(i</class>…

コンテナの要素を別のコンテナに移動する

C++

コンテナごとムーブ std::vector<T> v1; // ... std::vector<T> const v2(std::move(v1)); move_iterator を使ってムーブ std::vector<T> v; // ... std::list<T> const l( std::make_move_iterator(v.begin()), std::make_move_iterator(v.end())); move アルゴリズムを</t></t></t></t>…

C++ で FibBuzz

震源地: Codnote.net やりましょう. fibbuzz.cpp #if !defined(BOOST_PP_IS_ITERATING) #include <boost/preprocessor/iteration/iterate.hpp> #include <boost/preprocessor/slot/slot.hpp> #define BOOST_PP_VALUE 1 #include BOOST_PP_ASSIGN_SLOT(1) #define BOOST_PP_VALUE 1 #include BOOST_PP_ASSIGN_SLOT(2) #define BOOST_P…</boost/preprocessor/slot/slot.hpp></boost/preprocessor/iteration/iterate.hpp>

C++ で 2 進数を書く

BOOST_BINARY を使う やっぱり基本はマクロですね.ある車輪は使いましょう. #include <boost/utility/binary.hpp> #include <boost/static_assert.hpp> BOOST_STATIC_ASSERT((BOOST_BINARY(1001 1100 1011 111) == 0x4E5F)); テンプレートを使う C++ と言えばテンプレートメタプログラミング.あまり大きな数を</boost/static_assert.hpp></boost/utility/binary.hpp>…

固定長多次元配列のラッパ

std::array<std::array<T, M>, N> も std::vector<std::array<T, M> > も, &a[i][j] == &a[0][0] + i * M + j が成立するという意味での連続性が保証されるか分かったもんじゃないですねかわいい2011-09-12 10:24:33 via webstd::array, M> に要素の連続性の保証がないなら*1,生の多次元配列(</std::array<t,></std::array<t,>…

C++0x でスリープソート

C++

某 KUIS の院試でスリープソートが出題されたらしいので,以前話題になったときに書きかけてそのままにしていた C++0x での実装を晒しておきます. まず sleep.cpp がこちら. constexpr int f(int x, int y, int n) { return y == 0 ? 0 : f(x * 2, y - 1, …

Phoenix で variant を返す条件演算子

Boost.Phoenix の if で戻り値を返す - C++でゲームプログラミング Phoenix の if_else は then 節と else 節の common_type を返しますが,それらの型が異なる場合は variant に収めて返すという戦略もあるでしょう.Phoenix ではそのような条件演算子もユ…

MPL でカリー化

curryN<F> で,N-ary なメタ関数クラス F をカリー化します. #ifndef CURRY_HPP #define CURRY_HPP #include <boost/mpl/bind.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/mpl/protect.hpp> #include <boost/preprocessor/arithmetic/dec.hpp> #include <boost/preprocessor/cat.hpp> #include </boost/preprocessor/cat.hpp></boost/preprocessor/arithmetic/dec.hpp></boost/mpl/protect.hpp></boost/mpl/placeholders.hpp></boost/mpl/bind.hpp></f>

Variadic template template parameters に関して,ちょっとした疑問

C++

次のコードは gcc 4.6.0 と clang 2.9 でコンパイルの通るものです. template <class T = void> struct A {}; template <template <class ...> class U> struct B { U<> a; }; B<A> b; B<A> のインスタンス化中は U = A となっているわけですが,U<> が通るということは,U には A のデフォルト引数が使</a></a></template></class>…

C++0x で不動点コンビネータ

C++

Haskell では定義をそのまま書き下すことで不動点コンビネータを定義できるそうですが, fix :: (a -> a) -> a fix f = f (fix f) 魔法言語 C++0x も負けてはいないはずです. template <class F> struct fix_result { F m_f; template <class ...Args> auto operator()(Args &&...ar</class></class>…

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

C++

元ネタ constexpr で扱えて,実行時の効率もよいデータ構造+アルゴリズム - とくにあぶなくないRiSKのブログ arrayにpush_back, push_fonrt - bigsleepの日記 index_tuple の技法を使って,constexpr 関数の呼び出しを 2 回に抑える実装を考えました. #inc…

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

C++

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