C++ Advent Calendar 2013 9æ¥ç® ãBoost.Asioã¨Boost.Coroutineã§è±ã³ã¼ã«ããã¯ã
æ¬è¨äºã¯ C++ Advent Calendar 2013 9æ¥ç®ã¨ãã¦æ¸ããã¾ããã
ã¯ããã«
ãä¹
ãã¶ãã§ãã @fjnli ã§ãã
ããããã°ãå»å¹´ã¯C++é¢ä¿ã®Advent Calendarãæ¸ãã¦ãã¾ããã§ããã
æè¿C++ããã¾ã触ã£ã¦ããããBoostã¨ãC++14ã¨ãã®ãã©ãã¼ããã¾ãã§ãã¦ãã¾ããããC++åã®å£åãèããã¨æããä»æ¥ãã®é ã§ãã
C++æ¸ãããã§ãã
ãã¦ãæ¬è¨äºã§ã¯ãBoost.Asioã¨Boost.Coroutineã«ã¤ãã¦åãä¸ãã¾ããAsioã¨Coroutineã使ãã¨ãéåæå¦çã§ã³ã¼ã«ããã¯ãç¨ãããã¨ã«ããããã°ã©ã ã®è¦éãã®æªããæ¹åã§ãã¾ãããµã³ãã«ããã°ã©ã ããã¼ã¹ã«ãåºæ¬çãªä½¿ãæ¹ãç´¹ä»ãã¦ããããã¨æãã¾ãããªãï¼Boost.Asioã¨Boost.Coroutineãããããã©ãããå½¹å²ãããã©ã¤ãã©ãªãªã®ãã«ã¤ãã¦ã¯ï¼é·ããªã£ã¦ãã¾ãã¾ãã®ã§æ¬è¨äºã§ã¯æ±ãã¾ããï¼ãäºæ¿ãã ããï¼
ãã±ãäºãæ¸ãã¦ããããããã¾ããã®ã§ï¼ã³ã¡ã³ããªã©ããã¾ããã @fjnli ã¾ã§ãé¡ããã¾ãï¼Boost.Asioãããã§è©±ãé²ãã§ããï¼ä»ã®é¸æè¢ã¨ã®æ¯è¼ãå¼±ãç¹ã¯ä»å¾ã®èª²é¡ã§ãï¼Booståå¼·ä¼ãªã©ã§æ©ä¼ãããã°ï¼æ§è½ã«ã¤ãã¦èª¿æ»ãçºè¡¨ããããããã¾ããï¼
Version
Boost.Coroutineã¯Boost 1.53ãããBoost.Asioã®spawnã¯Boost 1.54ããå°å
¥ããã¦ãã¾ãã
æ¬è¨äºã®ç¯å²ã§ãã¨ãBoost.Coroutineãç´æ¥è§¦ããªãããå½±é¿ã¯ããã¾ããããBoost 1.55ããCoroutineã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ãv2ã¨ãªãã以åã®ãã®ã¨äºææ§ããªããªã£ã¦ãã¾ãã注æãã¦ãã ããã
ã¾ãããµã³ãã«ããã°ã©ã ã¯C++11ã§æ¸ãã¦ãã¾ãã®ã§ãC++11対å¿ç°å¢ã§ããã³ã³ãã¤ã«ã§ãã¾ããã
Callback
Asioã§éåæå¦çãè¡ãå ´åã¯ãéåæå¦çãç»é²ããéã«ãå¦çãå®äºããå¾ã«èªãã§ã»ããã³ã¼ã«ããã¯ã渡ãã¾ããããã°ã©ã ã®å¦çãæ¢ããªãããã«éåæå¦çãè¡ãã®ã§ããããã³ã¼ã«ããã¯ã渡ãã¨ããã¤ã³ã¿ã¼ãã§ã¤ã¹ã¯èªç¶ã§çã«ããªã£ã¦ããã¨æãã¾ããããããªãããã³ã¼ã«ããã¯ãç¨ããã¨ãã½ã¼ã¹ã³ã¼ãä¸ã§å¦çãåæ£ãã¦ãã¾ããããã°ã©ã ã®è¦éããæªããªãã¨ããåé¡ç¹ãããã¾ãã
ä¸è¨ã®å³ã®ãããªå¦çãããã¨ãã¾ãï¼ãã®å¦çãï¼åæçã«æ¸ãã¨æ¬¡ã®æ§ã«ãªãã¾ãï¼
A(); read(); B(); write(); C();
C++ã§ã¯ï¼ããã°ã©ã ã¯ã½ã¼ã¹ã³ã¼ãã®ä¸ããä¸ã«åãã¦å®è¡ããã¾ãã®ã§ï¼ç´è¦³çã§ããããããé ç½®ã§ãï¼æ¬¡ã«ã³ã¼ã«ããã¯ãç¨ãã¦éåæå¦ç風ã«æ¸ãã¦ã¿ã¾ãï¼
void after_read() { B(); async_write(after_write); } void after_write() { C(); } A(); read_async(after_read);
ãã®ããã«ãªãã¾ããï¼A, B, Cã¨é ã ã«å¦çããããã ãã«ããããããï¼2ã¤ã®é¢æ°ãå¿ è¦ã¨ãªãï¼å¦çãåæ£ãã¦ãã¾ãï¼ããã°ã©ã ã®å¯èªæ§ãä½ä¸ãã¦ãã¾ãï¼ã§ã¯ï¼C++11ã§å°å ¥ãããlambdaå¼ã使ãã¨ã©ããªãã§ããããï¼
A(); read_async([&] { B(); write_async([&] { C(); }); });
ã³ã¼ã«ããã¯ãé¢æ°ã¨ãã¦å®ç¾©ãããã¼ã¸ã§ã³ã¨æ¯ã¹ãã°ï¼å¦çA, B, Cãé ã«ä¸¦ãã§ããããï¼ãããããããªãã¾ããï¼ããããªããï¼lambdaå¼ãç¨ããæ¹å¼ã«ãåé¡ç¹ãããã¾ãï¼åæçã®ãããªãã©ãããªæ§é ã§ã¯ãªãï¼å ¥ãåãªæ§é ã¨ãªã£ã¦ãããã¨ã§ãï¼ä¾ãã°ï¼é£éããããå¦çãå¢ããã¨ã½ã¼ã¹ã³ã¼ããå³ã«å¯ã£ã¦ãã¾ãã¨ããåé¡ãããã¾ãï¼ã¾ãï¼ã½ã¼ã¹ã³ã¼ãä¸ã§ã®é çªã¨ï¼å®éã®å®è¡é çªãç°ãªã£ã¦ããã¨ããåé¡ãããã¾ãï¼ãµã³ãã«ã³ã¼ãã«å®è¡ãããé çªãã³ã¡ã³ãã¨ãã¦è¿½å ãã¾ãï¼
// (1) A(); // (2) read_async([&] { // (4) B(); // (5) write_async([&] { // (7) C(); // (8) }); // (6) }); // (3)
3, 6çªã®ä½ç½®ã«æ³¨ç®ãã¦ãã ããï¼ç´è¦³ã«åããå®è¡é åºã¨ãªã£ã¦ãã¾ãï¼3, 6çªã®ã¨ããã«å¦çãæ¸ããªããã°ããï¼ã¨ããèãæ¹ãå¯è½ã§ããï¼ã©ããã¦ããããããªãå£ãããã¾ãï¼ããã¯å¤æ°ã®å¯¿å½ã§ãï¼C++ã«ã¯GCãããã¾ããã®ã§ï¼GCãããè¨èªããããã£ããã§ãï¼
int x; // (1) A(); // (2) read_async([&] { int y; // (4) B(x); // ããã§ã¯ããxã¯æ»ãã§ãã // (5) write_async([&] { // (7) C(y); // ããã§ã¯ããyã¯æ»ãã§ãã // (8) }); // (6) }); // (3)
ãµã³ãã«ã³ã¼ãã«å¤æ°xã¨yã追å ãã¾ããï¼å¤æ°xã¯4çªã®ä½ç½®ããå©ç¨ã§ãã¾ãããï¼å¤æ°yã¯7çªã®ä½ç½®ããå©ç¨ã§ãã¾ããï¼å¤æ°xã4çªã§å©ç¨ããæã«ã¯æ¢ã«3çªãå®è¡ãããå¾ã§ããï¼å¤æ°xã®å¯¿å½ãåãã¦ãã¾ãï¼å¤æ°ãåç §ããã®ã§ã¯ãªãã³ãã¼ãããï¼ãã¹ã¦ãshared_ptrã§å ãã ãï¼çã®è§£æ±ºæ¹æ³ã¯ããã¾ããï¼ã©ã¡ããã³ã¹ããããããã¨ã«å¤ãã¯ããã¾ããï¼
æå¾ã«Coroutineã使ã£ãä¾ã示ãã¾ãï¼
A(); read_yield(); B(); write_yield(); C();
read_yieldã¨write_yieldã¯ï¼ã¹ã¬ããããããã¯ãããããã«ï¼ä»ã®coroutineã«å¦çãè²ã(yield)ãããªå®è£ ã«ãªã£ã¦ãããã®ã¨ãã¾ãï¼Coroutineçã¯é常ã«ãã£ããã¨ãã¾ããï¼Coroutineãéã®å¼¾ä¸¸ãã¨ããããã¨ï¼ããã§ã¯ãªãã¨æãã¾ãï¼ããªã¨ã³ãã·ã§ã³å¼ã§ã¯ãªãããyieldãããªãéãä»ã®Coroutineã«å¦çã移ããªãã¨ããç¹ã«æ³¨æããªããã°ãªãã¾ããï¼readã¨writeãCoroutineã«å¯¾å¿ãã¦ããªããã°ãªãã¾ããï¼ãã£ããï¼æ®éã®readãwriteãå¼ãã§ãã¾ãã¨ï¼Coroutineã®ã¡ãªãããã¾ã£ãããªããªã£ã¦ãã¾ãã¾ãï¼
Boost.Asioã§Coroutineã®ä½¿ãæ¹
Boost.Asioã§Coroutineã使ãã«ã¯ï¼boost::asio::spawnã使ãã¾ãï¼spawnã«æ¸¡ããã³ã¼ã«ããã¯ãCoroutineä¸ã§åãã¾ãï¼å¼æ°ã¨ãã¦yield_contextã渡ããã¾ããï¼ãããAsioã§Coroutineã使ãéµã¨ãªããªãã¸ã§ã¯ãã§ãï¼
asio::spawn(io_service, [&] (asio::yield_context yield) { });
ããã¦ï¼Asioã®éåæé¢æ°ã®ã³ã¼ã«ããã¯ã®ãããã«ï¼yield_contextã渡ãã¾ãï¼
asio::async_write(socket, buf, yield);
async_writeãéå§ãããã¨Coroutineãyieldããã¾ãï¼ããã¦ï¼async_writeãå®äºããã¨ï¼ããããåæå¦çã®ããã«async_writeããå¦çã帰ã£ã¦ãã¾ãï¼
å¦çã®æä¸ã§ã¨ã©ã¼ãçºçããã¨ï¼boost::system::system_errorä¾å¤ãçºçãã¾ãï¼ä¾å¤ã§ã¯ãªãï¼ã¨ã©ã¼ã³ã¼ããåãåãããå ´åã¯ï¼yield_context::operator []ã使ãã¾ãï¼
boost::system::error_code ec;
asio::async_write(socket, buf), yield[ec]);
ãã®ããã«æ¸ãã¨ï¼async_writeãã¨ã©ã¼ã«ãªã£ãéã«ï¼ä¾å¤ãæãããããããã«ï¼å¤æ°ecã«ã¨ã©ã¼ã³ã¼ããæ ¼ç´ããã¾ãï¼
ãµã³ãã«ã³ã¼ã
ã½ã±ããã使ã£ã¦éä¿¡ããç°¡åãªããã°ã©ã ãä½æãã¾ããï¼ãµã¼ãã¼å´ã§Coroutineã«ããéåæå¦çã使ç¨ãã¦ãã¾ãï¼ã½ã¼ã¹ã³ã¼ãå ¨ä½ã¯ Gist ã«ã¢ãããã¼ããã¦ãã¾ãï¼
ãµã³ãã«ããã°ã©ã ã¯ï¼ãµã¼ãã¼ãã¯ã©ã¤ã¢ã³ãããéããã¦ããæ°åãå ç®ãã¦ããã¨ããå 容ã§ãï¼åä½ä¾ãè¦ã¦é ããæ¹ãããããããã¨æãã¾ãï¼ã>>ãã§å§ã¾ãè¡ãå ¥åï¼ã-->ãã§å§ã¾ãè¡ããµã¼ãã¼ããã®ã¬ã¹ãã³ã¹ã示ãã¾ãï¼
ãµã¼ãã¼å´ã®å¦çã®ã¡ã¤ã³ã¨ãªãã®ã¯ï¼ä»¥ä¸ã®ã«ã¼ãã§ã (ãªãï¼ã¨ã©ã¼å¦çã¯ã¾ã£ãããã¦ãã¾ãã)ï¼
for (;;) { auto const n = asio::async_read_until(s, buf, "\n", yield[ec]); if (ec) break; /* (ç¥) */ acc += value; /* (ç¥) */ asio::async_write(s, asio::buffer(str), yield[ec]); if (ec) break; }
ã¯ã©ã¤ã¢ã³ããããã¼ã¿ãåãåãï¼å¤æ°accã«è¶³ãã¦ããã¾ãï¼ããã¦ï¼å¤æ°accã®å¤ãã¯ã©ã¤ã¢ã³ãã«è¿ãã¾ã (ãã¼ã¿ã¯æååã¨ãã¦ããåãããã¦ããããï¼å¤æå¦çãéã«å ¥ãã¾ã)ï¼yield_contextãç¨ãããã¨ã§ï¼ã³ã¼ã«ããã¯ãã¾ã£ãããªããã¨ã«æ³¨ç®ãã¦ãã ããï¼ãµã¼ãã¼å´ã¯1ã¹ã¬ããã§å®è¡ããã¦ãã¾ããï¼Coroutineã®åã§éåæã«å®è¡ããã¦ããããï¼è¤æ°ã®ã¯ã©ã¤ã¢ã³ãããã®æ¥ç¶ãåæã«åãã¦å¦çã§ãã¾ããï¼å¤æ°accã¯Coroutineæ¯ã«åé¢ãã¦ããããï¼å¤ãã¾ãããããªãã¨ãããã¾ããï¼
ã¾ã¨ã
åæçã®ã³ã¼ããå¥ã¹ã¬ããã§å®è¡ããã°ï¼è¦éããè¯ãï¼å¦çããããã¯ããªãããï¼ä¸äºè§£æ±ºã®ããã«è¦ãã¾ããï¼å¤ãã®å ´åã§ã¯ããã§ååã§ããã¨æãã¾ãï¼Boost.Coroutineã®ã¡ãªããã¯ï¼ã«ã¼ãã«ã®ä»å¨ããªãããï¼ä½æãç ´æ£ã®ãªã¼ãã¼ããããå°ãããã¨ã¨ï¼ã¹ã¬ããåãæ¿ããé«éã§ãããã¨ã§ãï¼ã¹ã¬ããæ°ãå¢ããã¨éãã表ãããã¨èãããã¾ãï¼ã¹ã¬ããã®æ§è½å·®ã ãã§ã¯ãªãï¼Asioã®ãªã¼ãã¼ããããããã¾ããï¼Asioã¯ã¿ã¤ãã¼ãã·ã°ãã«ã¨ãã£ããã®ãçµ±ä¸çã«æ±ãã¾ãï¼ãããã£ã¦ï¼æ§è½ã ãã§ãªã使ãåæãå«ãã¦æ¯è¼ãããªããã°ãããªãã¨ããã§ããï¼ä»ã®ã¨ãããããã®ãã¼ã¿ã¯ããã¾ããï¼ä»å¾ã®èª²é¡ã§ãï¼
宣ä¼
プログラミングの魔導書 Vol.3ã«ã10ãã¼ã¸ã»ã©ã®çãè¨äºã§ããå¯ç¨¿ãã¦ãã¾ããVol.3ã®ãã¼ãã¯ã並è¡ã並åãåæ£ãã¨ãªã£ã¦ããã並è¡ä¸çã®éç©ãåãããã«ã¯ã©ãããã°ãããã«ã¤ãã¦ã®è¨äºãæ²è¼ããã¦ãã¾ããåã¯OpenACCã¨ãããã¬ã¼ã ã¯ã¼ã¯ã«ã¤ãã¦æ¸ãã¦ãã¾ããOpenACCã¯GPUã®ãããªã¢ã¯ã»ã©ã¬ã¼ã¿ã§æ±ç¨è¨ç®ãè¡ãããã°ã©ãã³ã°ãè¨è¿°ããããã®ãã¬ã¼ã ã¯ã¼ã¯ã§ããOpenACCãç¨ããã¨ãã¡ã¢ãªç®¡çããã¼ã¿è»¢éã¨ãã£ãé¢åãªé¨åãã³ã³ãã¤ã©ã«ä»»ããããããã°ã©ã ã®çç£æ§ãããããã¨ã«å ãã¦ãOpenACCã³ã³ãã¤ã©ãæã¤ç°ãªãã¢ã¯ã»ã©ã¬ã¼ã¿éã§ã®ããã°ã©ã ã®å¯æ¬æ§ (Performance Portability) ãåä¸ãã¾ããä»æ§ãçå®ããã¦ãããã¾ãæéããã£ã¦ããããçºå±éä¸ãªä»æ§ã§ãããæ©è½é¢ãå種ã³ã³ãã¤ã©ã®å¯¾å¿ãå¼±ãã¨ãã£ãåé¡ã¯ããã¾ãããä»å¾ã®çºå±ãæå¾ ããããã¬ã¼ã ã¯ã¼ã¯ã§ãã
ãããå¹³è¡ä¸çã®éç©ã«èå³ããããªãã°ããªã³ã¯å ãè¦ã¦é ããã¨å¹¸ãã§ãããªããæ¸ç±çã¯äºç´ã®ã¿ã®éå®è²©å£²ãªããã§ãã®ã§ããæ©ãã«â¦!
Ariel AdC 11æ¥ç® ã·ãããã¿ããè¨èªãããã
ã¯ããã«
æ¬è¨äºã¯ Ariel Advent Calendar 2011 : ATND ã®11æ¥ç®ã§ãã12æ¥ã«ãªã¼ãã¼ã©ã³ãã¦ã¾ããã11æ¥ç®ã§ããããããªããã
ã·ãããã¿ããè¨èªãããã
ã¾ãã¯å®çªã®Hello worldãããããã§æ¸ãã¦ã¿ã¾ãããã
ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããããããããã ãããããããããããããããããããããããã
â¦ããããé·ãã§ããã
ããããã¯Brainfuckã®æ¹è¨ã®1ã¤ã§ããBrainfuckã§ã¯><+_.,[]ã®8è¨å·ã§è¡¨ç¾ããå½ä»¤åã"ãã"ã¨"ãã"ã ãã§è¡¨ç¾ãã¦ããçºããããé·ããªãã¾ããå½ä»¤ãããã³ã°ã¯ä»¥ä¸ã®éãã§ãã
> | ãããããã |
ãããããã | |
+ | ãããããã |
- | ãããããã |
. | ãããããã |
, | ãããããã |
[ | ãããããã |
] | ãããããã |
ããããã¯ãããé·ãè¨èªãªã®ã§æã§æ¸ãã®ã¯ç²ãã¾ãã(大ä½å·¦å³äº¤äºæéµãªã®ã§é«éã«ã¯å ¥åã§ããã¨æãã¾ãã)ããªã®ã§ãæ¸ãæã¯Brainfuckããæ©æ¢°çã«å¤æãã¾ãããããããããªã®ã§å½ç¶Emacsã§ããé¸æãããregionå ãããããã«å¤æããEmacs Lispãæ¸ããã®ã§ãããã¡ãã§ããã
(require 'cl) (defun bf-to-ariel (start end) (interactive "r") (loop with src = (buffer-substring-no-properties start end) for (c rep) in '((">" "ãããããã") ("<" "ãããããã") ("+" "ãããããã") ("-" "ãããããã") ("." "ãããããã") ("," "ãããããã") ("[" "ãããããã") ("]" "ãããããã")) for re = (regexp-quote c) do (setf src (replace-regexp-in-string re rep src)) finally (save-excursion (goto-char start) (delete-region start end) (insert src))))
Boost.Container stable_vector
ã¯ããã«
æ¬è¨äºã¯ partake.in 7æ¥ç®ã§ãã
stable_vector
Boost 1.48ããBoost.Containerã¨ããSTLäºæã®ã³ã³ããã©ã¤ãã©ãªãæ¡ç¨ããã¾ãããåºæ¬çã«ã¯boost::container::vectorãboost::container::stringã¨ãã£ãSTLäºæã®ã¯ã©ã¹ãæä¾ããã¦ãã¾ãããboost::container::stable_vectorã®ããã«STLã«ã¯ãªãç¬èªã®ã³ã³ãããæä¾ããã¦ãã¾ãã
(以ä¸ãstable_vectorã¨æ¸ããå ´åã¯boost::container::stable_vectorããvectorã¨æ¸ããæã¯std::vectorã示ããã®ã¨ãã¾ã)
stable_vectorã¯åã®ç¤ºãéã(è¦ç´ ã)å®å®ããvectorã§ããä¾ãã°vectorãç¨ãã¦ä»¥ä¸ã®æä½ãè¡ããã¨ãèãã¾ãã
vector<int> v; v.push_back(1); auto const it = v.begin(); for (int i = 2; i < 10; ++i) v.push_back(i); // âãã® *it ã¯å¤§ä¸å¤«? std::cout << *it;
æå¾ã®è¡ã«ãã *it ããã¦iteratorãåç §ãã¦ã大ä¸å¤«ãã©ããã¨ããåé¡ã§ããforã«ã¼ãã§åããã¦ããpush_backã«ãã£ã¦iteratorãç¡å¹å(invalidated)ãããããéµã¨ãªãã¾ããN3290ã«ããã¨ãvectorã®æ«å°¾ã«è¦ç´ ã追å ããéã« v.size() + 1 > v.capacity() ãªãã°iteratorãç¡å¹åãããã¨ããã¾ãããããã£ã¦ãä¸ã®åé¡ã®çãã¯ãv.begin()ã§iteratorãä¿åããæã®v.capacity()ã10以ä¸ãªãã°å¤§ä¸å¤«ãã¨ãªãã¾ãã
insertã¨eraseã®å ´åã話ã¯ãã1段éè¤éã«ãªãã¾ããinsertã®å ´åãv.size() + (æ¿å ¥ãããè¦ç´ æ°) > v.capacity()ãªãã°reallocationãçºçããå ¨ã¦ã®iteratorãç¡å¹åããã¾ããreallocationãçºçããªããªãã°ãæ¿å ¥ç¹ãããå¾ã®è¦ç´ ãæãiteratorã®ã¿ç¡å¹åããã¾ããeraseã®å ´åã¯ãreallocationã¯ä¸åèµ·ãããªãã®ã§ãåé¤ç¹ä»¥éã®è¦ç´ ãæãiteratorãç¡å¹åããã¾ãã
以ä¸ã®ä¾ã®ããã«ãvectorã¯æä½ã«ãã£ã¦iteratorãç¡å¹åããã¦ãã¾ããããé »ç¹ã«è¦ç´ ãæä½ããå ´åã使ãã«ããã¨æããå ´é¢ãããã¾ãããã®ãããªæã«ä½¿ãã®ãstable_vectorã§ãã
vectorã¯ãæ ¼ç´ããã¦ããè¦ç´ ã®é£ç¶æ§ãä¿è¨¼ãã¦ãããããè¦ç´ ã移åããæã«iteratorãç¡å¹åãããããã¨ããåé¡ãããã¾ãããstable_vectorã¯ãè¦ç´ ã並ãã§ããé åãé£ç¶ç¢ºä¿ããã®ã§ã¯ãªããå³1ã®ããã«è¦ç´ ãæããã¤ã³ã¿ãé£ç¶ãã¦ç¢ºä¿ããä»çµã¿ãåã£ã¦ãã¾ãããªã¹ãã®ããã§ãããè¦ç´ ãæããã¤ã³ã¿ã¯é£ç¶ãã¦ç¢ºä¿ããã¦ããããã©ã³ãã ã¢ã¯ã»ã¹ãå¯è½ã§ãã¾ããæ¿å ¥ãåé¤ãçºçãã¦ãæ ¼ç´ããã¦ããè¦ç´ ã¯ç§»åããªãããiteratorãç¡å¹åããããã¨ã¯ããã¾ãããã¾ããã³ã³ããä¸å¤®ã«è¦ç´ ãæ¿å ¥åé¤ããå ´åãvectorã§ã¯ãã以éã®å ¨è¦ç´ ãmoveããå¿ è¦ãããã®ã«å¯¾ãã¦ãstable_vectorã§ã¯ãã¤ã³ã¿ãcopyããã ãã§æ¸ã¿ãä½ã³ã¹ãã¨ãªãå ´åãããã¾ãã
å³1: stable_vectorã®è¦ç´ ã®é
ç½®ã®æ¦å¿µå³ã
ä¸æ¹ã§ãstable_vectorã¯è¦ç´ ã®å®å®æ§ãéè¦ãã¦ãããããå種æ§è½ã§ã¯vectorãlistã«å£ãé¢ãããã¾ããè¦ç´ ã®ã¢ã¯ã»ã¹ã®ããã«ä¸åä½è¨ã«éæ¥åç §ãããªãã¦ã¯ãããªããããvectorãããé ããªãã¾ãããè¦ç´ æ¬ä½ãé£ç¶ãã¦ããä¿è¨¼ããªãããããã£ãã·ã¥å¹çãæªããªãã§ããããã¾ããvectorãããå¤ãã®ã¡ã¢ãªãå¿ è¦ã¨ãã¾ããboostã®ããã¥ã¡ã³ãã«ããã¨ã(c + 1)p + (n + 1)(e + p) åã®ã¡ã¢ãªãå¿ è¦ã§ããã¨ããã¦ãã¾ããããã§ãc=capacity(), p=sizeof(T*), n=size(), e=sizeof(T)ã§ããvectorã§ã¯cÃeåã®ç©ºéããå¿ è¦ã¨ããªãã®ã¨æ¯ã¹ãã¨å¤ããã¨ããããã¾ãããã ããä¸é¨ã®å ´åã§stable_vectorã®æ¹ãçã¡ã¢ãªã§ããå ´åãããã¾ã(ã©ã®ãããªå ´åã«ãããªããã¯documentãèªãã§ãã ãã)ãc>>nã§ãããã¨ãå¤ããã¨ã¨ãè¦ç´ ãæ ¼ç´ããããã®é åããvectorã¯cÃeå確ä¿ãã¾ãããstable_vectorã¯nÃeåãã確ä¿ããªãããã§ãã(ã¾ãã«shrink_to_fitãããªãã°ãå ¨ãåç®ãããã¾ãããâ¦)
ã¾ã¨ã
vectorã®ç´æ¥çãªä»£æ¿ã¨ããããã¯ãlistã®ä»£æ¿ã®ä½ç½®ä»ãã«è¿ãã¨æãã¾ããè¦ç´ ã®å®å®æ§ãä¸å¤®ã¸ã®æ¿å ¥åé¤é度ãå¿ è¦ã§ããã¤ãã©ã³ãã ã¢ã¯ã»ã¹ãå¿ è¦ãªå ´åã«stable_vectorã¯å¨åãçºæ®ãã¾ãã
8æ¥ç®ã¯ id:tt_clown ããã®æ å½ã§ãããããããé¡ããã¾ãã
C++11æ代ã®threading
å§ãã«
æ¬è¨äºã¯ C++11 Advent Calendar 2011 : ATND ã®6æ¥ç®ã§ãã
std::thread
C++11æ代ã®threadã®åºæ¬ã¯ std::thread ã§ããããããã« #include
#include <iostream> #include <thread> void f() { std::cout << "f()" << std::endl; } int main() { std::thread thr(f); thr.join(); return 0; }
ãã®ããã°ã©ã ãå®è¡ãã㨠f() ã¨è¡¨ç¤ºãããã¯ãã§ããã³ã³ãã¤ã«ãã¦å®è¡ãã¦ã¿ã¾ãã
$ g++ -o thr thr.cpp -std=c++0x $ ./thr f() $
確ãã« f() ã¨è¡¨ç¤ºããã¾ãããã§ãããã ãã ã¨ãæ¬å½ã«ã¡ã¤ã³ã§ã¯ãªãã¹ã¬ããã§å®è¡ããã¦ããããããã¾ãããããããªæã¯std::this_thread::get_id()ã使ãã¾ãã
#include <iostream> #include <thread> void f() { std::cout << '[' << std::this_thread::get_id() << "] f()" << std::endl; } int main() { std::cout << '[' << std::this_thread::get_id() << "] main()" << std::endl; std::thread thr(f); thr.join(); return 0; }
å®è¡ãã¾ãã
$ g++ -o thr thr.cpp -std=c++0x $ ./thr [140006855132992] main() [140006838933248] f() $
mainãå®è¡ãããæã¨ãfãå®è¡ãããæã®thread idãç°ãªã£ã¦ãã¦ãå®è¡ã¹ã¬ãããç°ãªã£ã¦ãããã¨ããããã¾ãã
std::threadã®ã³ã³ã¹ãã©ã¯ã¿ã¯ãtemplate
#include <iostream> #include <thread> void f(int a, int b) { std::cout << a << '/' << b << std::endl; } int main() { std::thread thr(f, 1, 2); thr.join(); return 0; }
ãã®ããã°ã©ã ãå®è¡ããã¨
$ ./thr 1/2 $
ã¨è¡¨ç¤ºããã¾ãã
std::threadã«æ¸¡ãããé¢æ°ãªãã¸ã§ã¯ã(ä¾ã®ä¸ã§ã¯f)ã®è¿ãå¤åã¯voidã§ããå¿ è¦ã¯ããã¾ãããintã¨ãstd::stringã¨ãã§ã大ä¸å¤«ã§ãããstd::threadã¯è¿ãå¤ãæ¨ã¦ãã ãã§ãããå¼ã³åºãå ã®ã¹ã¬ããã¨åã渡ãããã·ã¹ãã ã¯ããã¾ãããããããã®ãããªæ©è½ãå¿ è¦ãªå ´åã¯std::futureãªã©ã使ç¨ãã¾ããã°ãã¼ãã«å¤æ°ã§ã解決ã§ãã¾ããããã¾ãã¹ãã¼ãã§ã¯ãªãã§ããã
C++ã§ã¯æ®æ®µãã¾ãæèããå¿ è¦ããã£ãããªãã£ãããã¾ãããC++ã«ã¯ä¾å¤ã¨ããåã£ã¦ãåãé¢ããªãâ¦ã¨ã¯è¨ãåããªãã·ã¹ãã ãããã¾ããã¹ã¬ãããæ±ãå ´åããã®ã¹ã¬ããã§ä¾å¤ãæããããæã«ã©ãããæåã«ãªãããææ¡ãã¦ãããã¨ã¯éè¦ã§ãã
ã¨ãããã¨ã§ä¾å¤ãæãã¦ã¿ã¾ãããã
#include <iostream> #include <thread> void f() { throw 1; } int main() { std::thread thr(f); thr.join(); return 0; }
å®è¡ãã¾ãã
$ g++ -o thr thr.cpp -std=c++0x $ ./thr terminate called after throwing an instance of 'int' Aborted $
ã¯ããè½ã¡ã¾ãããä¾å¤ãæãããã¦ããããæç²ãããªãã£ãå ´åãstd::terminateãå¼ã°ããã®ãC++11ã®ä»æ§ã§ã (N3290: 30.3.1.2.4)ãçµæ§å°ãã¾ãããä¸ã try catchãæ¸ãã®ã¯é¢åã§ããã親ã¹ã¬ããå´ã§ä¾å¤ãå¦çãããå ´åãããã¾ããC++11ã§ã¯ä¾å¤ãã¹ã¬ããéã§ããã¨ãããããã®æ©æ§ã¨ãã¦ãstd::exception_ptrãç¨æããã¦ãã¾ããããä¸ã ãããªãã®ã使ãã®ã¯ããã©ãããã§ãããããªãã¡ãstd::threadãç´æ¥ä½¿ãã®ã¯é常ã«ããã©ãããã®ã§ãé¿ãã¾ãããã¨ãããã¨ã§ãããããã«std::asyncãstd::packaged_taskã使ãã¾ãã
#include <iostream> #include <thread> #include <future> int f(int x, int y) { if (x < 0 || y < 0) throw "f"; return 100; } int main() { std::future<int> f1 = std::async(std::launch::async, f, 100, 200); std::cout << f1.get() << std::endl; std::future<int> f2 = std::async(std::launch::async, f, 100, -200); try { std::cout << f2.get() << std::endl; } catch (...) { std::cout << "catch!!!" << std::endl; } return 0; }
ãã®ããã°ã©ã ãå®è¡ããã¨ä»¥ä¸ã®æ§ã«ãªãã¾ãã
$ g++ -o thr thr.cpp -std=c++0x $ ./thr 100 catch!!! $
std::asyncã使ãã¨ãã©ã¤ãã©ãªãåæã«ããããé¢åãè¦ã¦ããã¾ããstd::asyncã®è¿ãå¤åã¯std::futureã§ããç´°ããæåã¯çç¥ãã¾ãããgetããã¨è¨ç®çµæã帰ã£ã¦ãã¾ããfã®ä¸ã§ä¾å¤ãé£ãã æã¯ãstd::future::getã§getããã¹ã¬ããå´ã«ä¾å¤ã移è²ããã¾ã (mainå¾åã®ããã«)ããªããstd::asyncã®å®è¡ããªã·ã¼ã¯implementation definedãªã®ã§ãã¹ã¬ããã使ã£ã¦è¨ç®ãããå ´åã¯std::launch::asyncãæ示çã«æ¸¡ãã¾ãã
ã¾ã¨ã
std::threadã¯é常ã«primitiveãªã®ã§ãå¯è½ãªãã°å¥ã®é«ã¬ãã«ãªä»çµã¿ã使ã£ãæ¹ãããã§ãã
C++11 advent calendar 7æ¥ç®ã¯id:kikairoyaããã§ãããããããé¡ããã¾ãã
libclangã§MPIã®é¢æ°ãæ½åºãã¦ã¿ã
æä½æ¥ã ã¨ããã©ãããããééãããã ã¨ãããã¨ã§libclangã使ã£ã¦ã¿ã¾ããã
ãããªãã¡ã¤ã«stub.cãç¨æãã¦ã
#include <mpi.h>
mpi_extractorã«é£ãããã¨ãMPIé¢æ°ã®ååãè¿ãå¤ã®åãå¼æ°ã®åãCSVã§åºåããã¾ãã
$ ./mpi_extractor stub.c MPI_Abort,int,MPI_Comm,int MPI_Accumulate,int,void *,int,MPI_Datatype,int,MPI_Aint,int,MPI_Datatype,MPI_Op,MPI_Win MPI_Add_error_class,int,int * MPI_Add_error_code,int,int,int * MPI_Add_error_string,int,int,char * [ç¥]
Asioã§epollã使ãã®ãããã
Linuxç°å¢ä¸ã§ã®Boost.Asioã¯ãæ¨æºã§epoll_reactorã使ç¨ãã¾ã(Asioã§ã¯IOå¤éåãè¡ãã¯ã©ã¹ãreactorã¨å¼ãã§ãã¾ã)ãããããªãããepollã¯ç»é²ã§ããfile descriptorã®ç¨®é¡ãselectãããçãã¨ããä»æ§ä¸ã®åé¡ãããã¾ããä¾ãã°ãã¡ã¤ã«(regular file)ãæãfile descriptorã¯ç»é²ã§ãã¾ããããã¶ãããã¡ã¤ã«ã«å¯¾ãã¦ãã«ããã«ããããå ´åã¯ãã«ã¼ãã«ãæä¾ãã¦ããaioã·ã¹ãã ã³ã¼ã«ã使ãã£ã¦ãã¨ãªãã§ãããã
ãã¦ãepollãregular fileãæãfile descriptorãæ±ããªããããasio::posix::stream_descriptorãregular fileãæ±ããªãã¨ããåé¡ãçºçãã¾ãããã®åé¡ãç°¡åã«è§£æ±ºããæ¹æ³ã¯ãæ§è½ãç ç²ã«ãã¦ãepollã§ã¯ãªãselectã使ãããã«ãããã¨ã§ããBOOST_ASIO_DISABLE_EPOLL ãdefineããã¨epollã®ä½¿ç¨ãæå¦ã§ãã¾ãã詳ãã㯠boost/asio/detail/config.hpp ãèªãã§ãã ããã
windowsåãã ã¨ãid:faith_and_brave:20110322 ã«ããããã«windows::stream_handleã使ããªãã¨ãããªãã£ãããé常ã«ããã©ãããã®ã§ãasio::file_streamã¿ãããªæ½è±¡çãªåã欲ããã¨ããã§ã¯ããã¾ãã
å¤ä¼ã¿çµã£ããã©bjamå§ãã¦ã¿ã¾ã 4æ¥ç®
å¤ä¼ã¿ã¯ããçµã£ã¦ãã¾ãã¾ããããbjamã¯ãã¾ã¼ã«ä½¿ã£ã¦ãã¾ãã
C++ã®ã½ã¼ã¹ã³ã¼ããã³ã³ãã¤ã«ããã ããªããbjamã¯æçãªã®ã§ã¯ãªãã§ããããã
â¦ã¨æãã¾ãããmakeæçã§ããâ¦ã
boost使ãããã§ã
3æ¥ç®ã«æ¸ããæ¹æ³ã§boostã使ã£ã¦ãããã®ã§ããããã£ããã®bjamãªã®ã§ãbjamã£ã½ã使ãã¾ããããä»åã®æ¹æ³ã¯boostã®ã½ã¼ã¹ããªã¼ãæã£ã¦å¿
è¦ã«å¿ãã¦ã³ã³ãã¤ã«ããè¨å®ã®ããããã£ã¹ã¯å®¹éçã«ã¯ä¸å©ã§ããã
ã¾ããboostã®ã½ã¼ã¹ãããä½ç½®ãbjamã«æãã¦ãããªãã¨ããã¾ãããæ¹æ³ã¯2ã¤ããã¾ãã
1ã¤ç®ã¯ç°å¢å¤æ°BOOST_ROOTã使ãæ¹æ³ã§ãã
$ export BOOST_ROOT=${HOME}/boost_1_47_0
ãã1ã¤ã¯user-config.jamã«è¨å®ãæ¸ãæ¹æ³ã§ãã
$ cat ~/user-config.jam using boost : 1.47 : <root>/home/fujita/boost_1_47_0
ããã¦ãããã¸ã§ã¯ãã®Jamrootãã¡ã¤ã«ã«ä»¥ä¸ã®æãæ¸ãã¾ãã
import boost ; boost.use-project ;
boost.use-projectã«ã¯ãã¼ã¸ã§ã³æå®ãå¯è½ã§ãã
boost.use-project 1.47 ;
ããã§ã/boost//regexã/boost//filesystemã¨ãã£ãã©ã¤ãã©ãªãå®ç¾©ããã¾ãããããã®ã¿ã§ããå ´åã¯/boost//headersãrequirementsã«è¿½å ãã¾ããä¾ãã°ãa.cppãfilesystemä»ãã§ã³ã³ãã¤ã«ãããå ´åã¯ã
exe a : a.cpp /boost/headers /boost//filesystem ;
ã¨ãã¾ãã