2015-04 pre-Lenexaのレビュー: N4390-N4399
N4390: Minimal incomplete type support for standard containers, revision 3
std::vector, std::list, std::forward_listの要素型に不完全型を認める提案。
これにより、以下のようなコードが書けるようになる。
struct Node
{
// この時点で、Nodeはまだ不完全型
std::vector<Node> nodes ;
} ; // Nodeはここから完全形
N4391: make_array, revision 4
std::arrayを返すstd::make_arrayの提案。文字列リテラルからそれぞれの文字のarrayを作るto_arrayも提案されている。
// std::array< int, 4 >
auto a = std::make_array( 1, 2, 3, 4 ) ;
// std::common_typeにより型が決定される
// std::array< long, 2 >
auto b = std::make_array( 2, 3L ) ;
// エラー、narrowing
auto c = std::make_array( 2, 3U ) ;
// OK、明示的な型指定
auto d = std::make_array<long>( 2, 3U ) ;
// エラー、narrowing
auto e = std::make_array<unsigned>( 2, 3U ) ;
// std::array< const char *, 1 >
auto f = std::make_array( "foo" ) ;
// std::array< char, 4 >
auto g = std::to_array( "foo" ) ;
[PDF注意] N4392: C++ Latches and Barriers
標準ライブラリにラッチとバリアーの提案。
latchとは、初期化時にカウンター値を設定する。各スレッドはカウンターをアトミックに減少させることができる。カウンターが0になるとready状態になり、latchに対してwaitをしていたスレッドのブロックが解かれる。
std::experimantal::latch l( 10 ) ;
void f()
{
l.count_down_and_wait( ) ;
}
barrierとは、繰り返し使えるlatchだ。
flex_barrierとは、ready状態になった時に呼び出す関数オブジェクトを設定できるbarrierだ。
[PDF注意] N4393: Noop Constructors and Destructors
何もしないno-opコンストラクターとデストラクターを追加する提案。
本当に何もしないコンストラクターとデストラクターが欲しい。バイト列を操作して、それをそのままクラスのオブジェクトとして扱うような場合だ。用途としてはdestructive moveや、オブジェクトの内部表現のバイト列をディスクに読み書きしたりする場合だ。
提案では、文法例はさまざまある。仮に提案されている文法は、何らかのキーワード(バイク小屋議論を避けるために仮に__COOKIE__とする)をコンストラクターとデストラクターに渡すものだ。
struct X { ... } ;
void f()
{
alignas(X) char buf[sizeof(X)] ;
auto p = new(buf) X( __COOKIE__ ) ; // no-op constructor
p->~X( __COOKIE__ ) ; // no-op destructor
}
no-opは本当に何もしない。バイト列がクラスの表現として正しいかどうかはプログラマーが責任を持つ。
ポリモーフィックな型はno-opコンストラクターを使えない。(vtableなどの実装が操作する隠しバイト列があるため)
自動ストレージ上に確保されたオブジェクトに対してno-opデストラクターを呼び出しても、依然として自動的にデストラクターは呼び出される。
struct X { ... } ;
void f()
{
X x ;
x->~X( __COOKIE__ ) ; // no-op デストラクター
// デストラクターは呼び出される。
}
どうも、reinterpret_castとあまり変わらない気がする。
論文では、将来的な拡張案として、ポリモーフィック型に対応したり(vtableなどの隠しバイト列だけを初期化する)、自動的なデストラクター呼び出しを抑制するなどの案をあげているが、これは今の提案の骨子ではないとして今回は提案しないとしている。
N4394: PL22.16/WG21 draft agenda: 4-9 May 2015, Lenexa KS/US
Lenexa会議の日程。
[PDF注意] N4395: SIMD Types: ABI Considerations
SIMDベクトル型を標準に追加する場合のABIに対する考察。
単一アーキテクチャーの中の複数のマイクロアーキテクチャーにどうやって対応したらいいのか。例えば、x86-64は、SSE, AVX, AVX2という複数のSIMDベクトル演算のマイクロアーキテクチャーが存在する。それぞれ最も効率の良いABIが異なる。異なる翻訳単位をまたぐと、ABIが一致しない。さてどうするのか。
論文では、ポリシーベースの実装が最も良いとしている。しかし、それは実装依存のアーキテクチャーを規格に盛り込まなければならないような気がする。
[PDF注意] N4396: National Body Comments: PDTS 19841, Transactional Memory
Transactional Memoryに対するNBコメント。
N4397: A low-level API for stackful coroutines
スタックフルコルーチンや協調型マルチタスクを実装するための低級APIの提案。Boot.Contextベースを参考に設計されている。
stacklessとstackfulの違いや仕組みの解説が初歩的なところからよく書かれているので興味深い。
[PDF注意] N4398: A unified syntax for stackless and stackful coroutines
stacklessコルーチンとstackfulコルーチンの文法を統一しようという提案。
概要
本論文はstacklessとstackfulコルーチンの統一文法を提案する。文法はN4397を元にしている。
主要な機能は、
- 変数やコンテナーに格納できる第一級オブジェクト
- resumableキーワードを用いたlambda風の式の導入
- 実行のシンメトリックな(訳注:呼び出し元以外の任意の実行媒体に実行を渡せる)転送。アシンメトリックな転送よりも高級な実行制御が可能になる。
- 通常の関数の呼び出しとreturnは影響を受けない。
stacklessとstackfulの統合というのは、
関数をみて、
コンテキストスイッチが発生していなければ、通常の関数。
トップレベルでコンテキストスイッチが発生していれば、stackless コンテキスト
その他の場合、stackfulコンテキスト
だそうだ。
N4397のstd::execution_contextとほぼ同じ設計になっているが、lambda風式がhint属性を取らず、stacklessかstackfulかは、コンパイラーが判断するようになっている。
N4399: Technical Specification for C++ Extensions for Concurrency, Working Draft
Concurrency TSのドラフト
futureの改良
futureがready状態になったときに実行される関数オブジェクトを指定できるthenや、複数のfutureがすべてready状態になった時に実行される関数オブジェクトを指定できるwhen_all, 逆に、ひとつでもready状態になった時のwhen_any。最初からready状態になっているfutureを作るmake_ready_future。最初から例外状態になっているfutureを作るmake_exceptional_future。
latchとbarrierライブラリ
初期化時にカウンター値を指定して、アトミックにデクリメントし、カウンター0になるまで実行をブロックできる使い捨てのlatch。再利用ができるbarrier。カウンターが0になった時に実行される関数オブジェクトを指定できるflex_barrier。
atomicなshared_ptr
atomicに操作できるatomic_shared_ptrとatomic_weak_ptr
ドワンゴ広告
C++標準化委員会の論文がたまっている。
ドワンゴは本物のC++プログラマーを募集しています。
CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0