最近気になったC++のライブラリとか


# はじめに

先日 [C++初心者会](http://kbkz.connpass.com/event/13905/) と [Boost.勉強会 #17 東京](http://connpass.com/event/14355/) に参加した。この2つの勉強会で紹介されたライブラリやC++1zで組み込まれる予定の機能などから、私が気になったものを紹介する。

勉強会の内容については [歌舞伎座.tech #8 「C++初心者会」を開催した](http://cpplover.blogspot.jp/2015/05/tech-8-c.html) や [Boost.勉強会 #17 東京に参加してきた](http://qiita.com/kazatsuyu/items/6a2d1845dff26e6e785d) で紹介されている。

# LINQ for C++

 * 発表者: mikiemon_h さん

 * 資料： [LINQ for C++のご紹介](http://www.slideshare.net/miki_hirofumi/boost17-cpplinq)

## LINQとは

LINQとは言語統合型クエリ(Language Integrated Query)のことで、コードでクエリ式の記述を可能にする機能のこと。 **LINQがあるからC#を使う** という人がいるほど便利な機能である( [グラニがC#にこだわる理由](http://gihyo.jp/dev/serial/01/grani/0001?page=2) )。

LINQは.NET Framework3.5から利用できるようにり、C#の他、VBやF#などでも利用できるのだが、C++/CLIでは利用できないし今後も対応する予定はないらしい。そのためC++でLINQを利用したい場合、LINQと似た機能を提供してくれるライブラリ [LINQ for C++](http://cpplinq.codeplex.com/) を使うことになる。

## サンプル

 [GitHub](https://github.com/mrange/cpplinq) から ```clone``` したヘッダをインクルードするだけで簡単に使える。

```sample.cpp
#include <vector>
#include <iostream>
#include "cpplinq/CppLinq/cpplinq.hpp"

int main()
{
    using namespace cpplinq;

    const int ints[] = { 
        3, 1, 4, 1, 10, 7, 2,
    };  

    from_array(ints)
        >> where([](int n) { return n % 2 == 0; })         // 偶数要素を取り出し
        >> orderby([](int n) { return n; })                // 昇順に並べて
        >> for_each([](int n) { std::cout << n << " "; }); // 各要素を出力する

    return 0;
}
```

# Mach7

C++初心者会でチラッと話題に出た、C++向けのパターンマッチングライブラリ( [Mach7: Pattern Matching for C++](https://github.com/solodon4/Mach7) )。

## パターンマッチングとは

パターンマッチングとは、コードをシンプルにする抽象メカニズムのこと。本ライブラリを使用することで、関数型スタイルのパターンマッチングをC++で行うことが可能となる。

## サンプル

[GitHub](https://github.com/solodon4/Mach7) から引用。

```sample.cpp
// Fibonacci numbers
int fib(int n)
{
    var<int> m;

    Match(n)
    {
      Case(1)     return 1;
      Case(2)     return 1;
      Case(2*m)   return sqr(fib(m+1)) - sqr(fib(m-1));
      Case(2*m+1) return sqr(fib(m+1)) + sqr(fib(m));
    }
    EndMatch
}
```

# unique_resource

 * 発表者: okdshin さん

 * 資料: [unique_ptrにポインタ以外のものを持たせるとき](http://www.slideshare.net/ShintarouOkada/unique-resource150517okdshin)

## unique_resourceとは

次期標準ライブラリに加えることが提案されているライブラリ。```unique_ptr``` をポインタ以外にも適用できるよう一般化したもの。

## サンプル

発表資料から抜粋。

```sample.cpp
namespace others { /* 省略 */ }

decltype(auto) make_unique_handle()
{
    return std::experimental::make_unique_resource(
            others::GetHandle(), &others::ReleaseHandle);
}

int main()
{
    auto h1 = make_unique_resource();
    auto h2 = make_unique_resource();
    auto h3 = make_unique_resource();

    // move可能
    // もともとのh2のハンドルはリリース
    h2 = std::move(h3);

    // 生のハンドルにアクセス可能
    std::cout << h1.get() << std::endl;

    // 明示的にハンドルをリリース可能
    h1.reset();
    return 0;
}
```

自分自身でRAIIクラスを作成する場合、

 * 例外安全性は確保できているか

 * ムーブの実装はできているか

 * リソース漏れは本当にしていないか

などなど、注意すべき点が多くて面倒であるが、 ```make_resource``` ならその辺がちゃんとしていて便利。

## 参考

 * [N4189-Generic Scope Guard and RAII Wrapper for the Standard Library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf)

# Siv3D

 * 発表者: @Reputeless

 * 資料: [Siv3D で楽しむゲームとメディアアート開発](http://www.slideshare.net/Reputeless/siv3d)

## Siv3Dとは

C++で楽しく簡単にゲームやメディアアートを開発できるライブラリ。

お絵描きアプリは10行、Kinectの情報可視化は15行、ブロック崩しゲームは28行でできるらしい。

**プログラミングを楽しく** をコンセプトとしており、教育市場での利用を想定している。業務での使用を想定しているわけではないので、利用できるOSはWindows 32ビット版に限定される(Windows 64ビット版は32ビット版として動作、MacやAndroidなどには非対応)。将来的にはMacなどでの利用も検討しているらしい。

## 参考

Siv3Dを使ったデモも載っているので、ぜひ見て欲しい。

 * [『未踏の世界』 C++で簡単にゲームやメディアアートを作れるライブラリ「Siv3D」](https://codeiq.jp/magazine/2015/03/21929/)

# Boost.Container

 * 発表者: @cpp_akira さん

 * 資料: [Boost.Container特有の機能](http://www.slideshare.net/faithandbrave/boost-container-feature)

## Boost.Containerとは

標準コンテナの最新仕様を、標準規格の更新を待たず、すぐに試せることを目的としたライブラリ。標準ライブラリにほとんど同じ機能があるためBoost.Containerが利用されるケースは多くないが、 **Boost.Containerに特有の便利な機能** もある。

## 標準コンテナとの違い

 * 要素のデフォルト値を未初期化にする

   ```std::vector``` では要素数を伸張するとき、伸張した分の要素を値初期化するため巨大な動的配列を作る際は初期化のコストが無視できなくなる。一方、 ```boost::container::vector``` は要素を未初期化にする伸張を提供している。

 * realloc機能に対応したアロケータ

   ```std::vector``` は要素を伸張した場合、新たな別の場所により大きな領域を確保して要素を移動する。一方、 ```boost::container::vector``` は ```boost::container::allocator<T, 2>``` を使用すると、今確保しているメモリを伸張してくれる。

 * 例外送出のカスタマイズ

   Boost.Containerでは、例外送出のところで ```std::abort``` を呼び出して異常終了する、例外送出の方法を自分で決定するなど、例外送出についてカスタマイズ方法を提供しており、例外発生時にログやバックトレースを出力することができる。

 * 連想コンテナの拡張オプション

   連想コンテナのツリー構造を指定できる。

# 最後に

他の方の発表資料は下記サイトから閲覧できるので、興味のある方は一読してみると良いかと思います。

 * [歌舞伎座.tech#8「C++初心者会」](http://kbkz.connpass.com/event/13905/presentation/)

 * [boostjp](http://boostjp.github.io/study_meeting/study17.html)