--- /dev/null
+¶äÅ·¥é¥¤¥Ö¥é¥ê ¥é¥¤¥»¥ó¥¹ version 1.1
+
+
+Ëܥ饤¥Ö¥é¥ê¤Ï¡Ö¸½¾õ¤Î¤Þ¤Þ¡×¤Ç¡¢ÌÀ¼¨¤Ç¤¢¤ë¤«°ÅÌۤǤ¢¤ë¤«¤òÌä¤ï¤º¡¢²¿¤é¤ÎÊݾڤâ¤Ê¤¯Ä󶡤µ¤ì¤Þ¤¹¡£Ëܥ饤¥Ö¥é¥ê¤Î»ÈÍѤˤè¤Ã¤ÆÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»³²¤Ë¤Ä¤¤¤Æ¤â¡¢ºî¼Ô¤Ï°ìÀÚ¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¤â¤Î¤È¤·¤Þ¤¹¡£
+
+°Ê²¼¤ÎÀ©¸Â¤Ë½¾¤¦¸Â¤ê¡¢¾¦ÍÑ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò´Þ¤á¤Æ¡¢Ëܥ饤¥Ö¥é¥ê¤òǤ°Õ¤ÎÌÜŪ¤Ë»ÈÍѤ·¡¢¼«Í³¤Ë²þÊѤ·¤ÆºÆÈÒÉÛ¤¹¤ë¤³¤È¤ò¡¢¤¹¤Ù¤Æ¤Î¿Í¤Ëµö²Ä¤·¤Þ¤¹¡£
+
+£±¡¥Ëܥ饤¥Ö¥é¥ê¤Î½Ð¼«¤Ë¤Ä¤¤¤Æ¡¢µõµ¶¤Îɽ¼¨¤ò¤·¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤¢¤Ê¤¿¤¬¥ª¥ê¥¸¥Ê¥ë¤Î¥é¥¤¥Ö¥é¥ê¤òºîÀ®¤·¤¿¤È¼çÄ¥¤·¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤¢¤Ê¤¿¤¬Ëܥ饤¥Ö¥é¥ê¤òÀ½ÉÊÆâ¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢À½ÉʤÎʸ½ñ¤Ë¼Õ¼¤òÆþ¤ì¤Æ¤¤¤¿¤À¤±¤ì¤Ð¹¬¤¤¤Ç¤¹¤¬¡¢É¬¿Ü¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+£²¡¥¥½¡¼¥¹¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢¤½¤Î¤³¤È¤òÌÀ¼¨¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¥ª¥ê¥¸¥Ê¥ë¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤¢¤ë¤È¤¤¤¦µõµ¶¤Îɽ¼¨¤ò¤·¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤¿¤À¤·¡¢¸¶·¿¤òα¤á¤Ê¤¤Äø¤Ë²þÊѤµ¤ì¤¿¥³¡¼¥ÉÊҤˤĤ¤¤Æ¤Ï¡¢¤½¤Î½Ðŵ¤¬Ëܥ饤¥Ö¥é¥ê¤Ë¤¢¤ë»Ý¤òÌÀ¼¨¤¹¤ëɬÍפϤʤ¤¤â¤Î¤È¤·¤Þ¤¹¡£
+£³¡¥¥½¡¼¥¹¤ÎÈÒÉÛʪ¤«¤é¡¢¤³¤Îɽ¼¨¤òºï½ü¤·¤¿¤ê¡¢É½¼¨¤ÎÆâÍƤòÊѹ¹¤·¤¿¤ê¤·¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤¿¤À¤·¡¢ÆüËܸì¤Î¥¨¥ó¥³¡¼¥ÉÊý¼°¤òÊÑ´¹¤¹¤ë¤³¤È¤Ïǧ¤á¤é¤ì¤Æ¤¤¤Þ¤¹¡£
+
+¸¶Ê¸¡§ http://sourceforge.jp/projects/opensource/wiki/licenses%2Fzlib_libpng_license
+Ëܥ饤¥Ö¥é¥ê¤Ø¤ÎŬÍѤ˺ݤ·¡¢¼ã´³É½¸½¤òÊѹ¹¤·¤Æ¤¤¤Þ¤¹¡£
+
+
+Copyright (c) 2009 SubaruG, All rights reserved.
+This document is encoded with EUC-JP.
+
+
+
+°Ê²¼¤Ï¶äÅ·¥é¥¤¥Ö¥é¥ê¤Ç»ÈÍѤµ¤»¤Æ夤¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥ê¤È¡¢¤½¤Î¥é¥¤¥»¥ó¥¹¤Î°ìÍ÷¤È¤Ê¤ê¤Þ¤¹¡£
+
+
+¡¦Boost C++ Libraries http://www.boost.org/
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+http://www.boost.org/users/license.html
--- /dev/null
+¶äÅ·¥é¥¤¥Ö¥é¥ê¡Ê Ginten C++ Libraries ¡Ë ´Ê°×Èǥɥ¥å¥á¥ó¥È
+
+written by SubarG, gintensubaru@hotmail.com
+This document is encoded with EUC-JP.
+
+
+¡¦Ãí°Õ»ö¹à
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¡¢Àµ¼°¤Ê¥É¥¥å¥á¥ó¥È¤¬´°À®¤¹¤ë¤Þ¤Ç¤Î¡Ö¤Ä¤Ê¤®¡×¤È¤·¤ÆÍÑ°Õ¤·¤¿¤â¤Î¤Ç¤¹¡£Àµ¼°¤Ê¥É¥¥å¥á¥ó¥È¤¬´°À®¤·¤¿ºÝ¤Ë¤Ï¡¢¤³¤ÎÆâÍƤÏÂçÉý¤Ëºï¤é¤ì¤ë¤«¡¢¤¢¤ë¤¤¤Ïºï½ü¤µ¤ì¤ëͽÄê¤Ç¤¹¤Î¤Ç¤´Î»¾µ¤¯¤À¤µ¤¤¡£
+Àµ¼°¤Ê¥É¥¥å¥á¥ó¥È¤¬½ÐÍè¤ë¤Þ¤Ç¤Î´Ö¡¢¥é¥¤¥Ö¥é¥ê¤Î»ÈÍÑË¡¤Ï¡¢¤½¤Î¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë( gintenlib/ Æâ)¤ä¥Æ¥¹¥È¥³¡¼¥É( tests/ Æâ)¤Î³Æ¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ¤¤¤¿¤À¤¯¤è¤¦¤ª´ê¤¤¤·¤Þ¤¹¡£
+
+
+¡¦¤´°§»¢
+
+¤³¤ÎÅ٤϶äÅ·¥é¥¤¥Ö¥é¥ê¤ò¥À¥¦¥ó¥í¡¼¥É夤¢¤ê¤¬¤È¤¦¤´¤¶¤¤¤Þ¤¹¡£
+¶äÅ·¥é¥¤¥Ö¥é¥ê¤È¤Ï¡¢¡Ö¤Ê¤¯¤Æ¤â¤¤¤¤¤¬¤¢¤ë¤È¾¯¤·ÊØÍø¡×¤È¤¤¤¦¥³¥ó¥»¥×¥È¤Î¸µ¡¢¼ç¤Ë¶äÅ·¿ïÉ®½¸ http://d.hatena.ne.jp/gintenlabo/ Æâ¤ÇÀ½ºî¤µ¤ì¤Æ¤¤¤ë¡¢»äŪ C++ ¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+»äŪ¡¢¤È¤¤¤¦Ä̤ꡢËÜÍèŪ¤Ë¤Ï¼«Ê¬¤Î°Ù¤À¤±¤Ëºî¤Ã¤¿¥³¡¼¥ÉÃÇÊÒ½¸¤Ê¤Î¤Ç¤¹¤¬¡¢»È¤Ã¤Æ¤¤¤Æ»×¤Ã¤¿¤è¤ê»È¤¤¾¡¼ê¤¬¤è¤¤¤Î¤Ç¡¢À޳ѤÀ¤«¤é¥é¥¤¥Ö¥é¥ê¤È¤·¤Æ¤Þ¤È¤á¤Æ°ìÈ̸ø³«¤·¤è¤¦¡¢¤È¤¤¤¦¤³¤È¤Ç¡¢£²£°£°£·Ç¯£±£²·îº¢¤«¤é¾¯¤·¤º¤Ä¤Ç¤¹¤¬³«È¯¤ò¿Ê¤á¤Æ¤¤Þ¤·¤¿¡£¤½¤·¤ÆÆóǯ¤¿¤Ã¤¿º£¡¢¤è¤¦¤ä¤¯¤½¤ì¤Ê¤ê¤Îµ¬ÌϤΥ饤¥Ö¥é¥ê¤È»×¤¨¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤Î¤Ç¡¢²þ¤á¤Æ version 1.0.0 ¤È¤·¤Æ»×¤¤Àڤ俺ÆÊÔ¤ò¹Ô¤¤¡¢¤è¤¦¤ä¤¯¤³¤¦¤·¤Æ¤Þ¤È¤Þ¤Ã¤¿¥é¥¤¥Ö¥é¥ê¤È¤·¤ÆÀ¤¤Ë½Ð¤¹¤Ë»ê¤Ã¤¿¼¡Âè¤Ç¤¹¡£
+¤½¤¦¤¤¤¦·Ð°Þ¤¬¤¢¤ë¤¿¤á¡¢¼ýÏ¿¤µ¤ì¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥ê¤ÏÈó¾ï¤Ë»¨Â¿¤Ç¡¢Æä˷è¤á¤é¤ì¤¿Êý¸þÀ¤È¤¤¤¦¤â¤Î¤â¸ºß¤·¤Þ¤»¤ó¡£°ì±þ¡¢¥³¥ó¥»¥×¥È¤¬¡Ö¤Ê¤¯¤Æ¤â¤¤¤¤¤¬¤¢¤ë¤È¾¯¤·ÊØÍø¡×¤Ç¤¢¤ë°Ê¾å¡¢¤¢¤¯¤Þ¤Çµ¤·Ú¤Ë»È¤¨¤ë¤³¤È¤Ë½ÅÅÀ¤òÃÖ¤¤¤Æ³«È¯¤·¤Æ¤Ï¤¤¤ë¤Î¤Ç¤¹¤¬¡¢¤½¤ì¤¹¤é¼é¤ì¤Ê¤¤¤³¤È¤â¿¡¹¡£¤³¤ÎÊÕ¤ê¤Ï¥Ð¡¼¥¸¥ç¥ó¥¢¥Ã¥×¤ò½Å¤Í¤ë¾å¤Ç¾¯¤·¤º¤ÄÂåÂؼêÃʤòÁý¤ä¤·¤Æ¤¤¤¯¤³¤È¤ÇÂбþ¤·¤è¤¦¤«¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£
+
+¤Ç¤Ï¶ñÂÎŪ¤Ë¡¢¤É¤ó¤Ê¥é¥¤¥Ö¥é¥ê¤¬¤¢¤ë¤«¡¢°ìÉô¤Ç¤¹¤¬¾Ü¤·¤¯¾Ò²ð¤·¤¿¤¤¤È»×¤¤¤Þ¤¹¡£
+¤Þ¤º list_format ¡£¼Â¤ò¸À¤¦¤È¡¢¤³¤ì¤³¤½¤¬¶äÅ·¥é¥¤¥Ö¥é¥ê¤òºî¤í¤¦¤È»×¤Ã¤¿ºÇÂç¤ÎÆ°µ¡¤Ç¤¢¤Ã¤¿¤ê¤·¤Þ¤¹¡£ µ¡Ç½¤Ï¡¢Å¬Åö¤ÊÇÛÎó int a[5]; ¤ä¥³¥ó¥Æ¥Ê std::vector a; ¤ËÂФ·¡¢cout << gintenlib::list_format( a ); ¤È¤«½ñ¤¯¤À¤±¤Ç "( 1, 2, 3, 4, 5 )" ¤Î¤è¤¦¤Ëɽ¼¨¤Ç¤¤ë¡¢¤È¤¤¤¦¤À¤±¤Î¤â¤Î¤Ç¤¹¡£Ê̤ˤʤ¯¤Æ¤â¤É¤¦¤È¤¤¤¦¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¤¢¤ë¤Ê¤é¤¢¤ë¤Ç¥Ç¥Ð¥Ã¥°¤Î¤È¤¤È¤«¤Ë¾¯¤·ÊØÍø¤Ç¤·¤ç¤¦¡©
+¤â¤Ã¤È¼ÂºÝŪ¤ËÌò¤ËΩ¤Ä¤è¤¦¤Ê¥é¥¤¥Ö¥é¥ê¤â¤¢¤ê¤Þ¤¹¡£ new_ ¤¬¤½¤ÎÂåɽÎã¤Ç¤¹¡£¤³¤ì¤Ï¡¢¡Ö gintenlib::new_<T>(°ú¿ô¥ê¥¹¥È) ¡×¤È½ñ¤¯¤³¤È¤Ë¤è¤ê¡¢¡Ö boost::shared_ptr<T>( new T(°ú¿ô) ) ¡×¤¬¸Æ¤Ð¤ì¤ë¡¢¤È¤¤¤¦¤À¤±¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤¹¤¬¡¢¤¿¤È¤¨¤Ð shared_ptr ¤ò°ú¿ô¤Ë¤È¤ë´Ø¿ô¤Ë¿·¤·¤¯¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤Ã¤ÆÅϤ·¤¿¤¤¡¢¤È¤¤¤¦¤È¤¤Ë¥½¡¼¥¹¤¬¤À¤¤¤Ö´Ê·é¤Ë¤Ê¤ë¡¢¤È¤¤¤¦ÍøÅÀ¤¬¤¢¤ê¤Þ¤¹¡Ê¼ÂºÝ¤Ë¤Ï¤â¤Ã¤È½ÐÍè¤ë¤³¤È¤Ï¿¤¤¤Ç¤¹¡£¾Ü¤·¤¯¤Ï¥Ø¥Ã¥À¤Ë½ñ¤¤¤Æ¤¢¤ë¤Î¤Ç¤½¤Á¤é¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£¤½¤ó¤Ê¤ÎÊ̤ˤʤ¯¤Æ¤â¤¤¤¤¤±¤É¡¢¤¢¤Ã¤¿¤é¤¢¤Ã¤¿¤Ç¾¯¤·ÊØÍø¤½¤¦¤Ç¤·¤ç¤¦¡©
+¤µ¤é¤Ë¶äÅ·¥é¥¤¥Ö¥é¥ê¤ÎÆÃħ¤È¤·¤Æ¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤Î¥Ø¥Ã¥À¤ò½ñ¤¯¤È¤¤Ë½ÐÍè¤ë¸Â¤ê³Ú¤ò¤·¤è¤¦¤È¤¤¤¦È¯ÁÛ¤«¤é¡¢¼ÂÁõÊä½õ·ÏÅý¤Î¥é¥¤¥Ö¥é¥ê¤¬Èó¾ï¤Ë¿¤¤ÅÀ¤¬Í¤ê¤Þ¤¹¡£ SafeBool ¥¤¥Ç¥£¥ª¥à¤òÄ󶡤¹¤ë bool_comparable ¤ä¡¢¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿ºî¤ë¤È¤¤Ë get() ´Ø¿ô¤À¤±ÄêµÁ¤¹¤ì¤Ð¼«Æ°¤Ç·¿ÄêµÁ¤ä±é»»»Ò¿½ÅÄêµÁ¤ò¤·¤Æ¤¯¤ì¤ë pointer_facade ¡¢ boost::enable_if ¤òû¤¤¥Þ¥¯¥í¤Ç°·¤¨¤ë¤è¤¦¤Ë¤·¤¿ preprocessor.enable_if ¤Ê¤É¡¢¤³¤Î¼ê¤ÎÊØÍøµ¡Ç½¤ÏÈó¾ï¤Ë¿¤¯¡¢¤Þ¤¿¼ÂÍÑÀ¤â¾¤ËÈæ¤Ù¤ÆÃʰ㤤¤Ë¹â¤¯¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¶½Ì£¤¬¤¢¤ì¤Ðõ¤·¤Æ¤ß¤ë¤ÈÌÌÇò¤¤¤Ç¤·¤ç¤¦¡£
+
+¤È¡¢¾¯¤·Ïä¬Ä¹¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤·¤¿¡£¤â¤Ã¤È¿§¡¹¸ì¤ê¤¿¤¤¤Î¤Ï»³¡¹¤Ç¤¹¤¬¡¢¤½¤ì¤ÏÀµ¼°¤Ê¥É¥¥å¥á¥ó¥È¤¬½ÐÍè¤Æ¤«¤é¤Ë¤·¤¿¤Û¤¦¤¬¤è¤µ¤½¤¦¤Ç¤¹¡£
+»È¤¦Â¦¤È¤·¤Æ¤â¡¢Ä¹¤¤°§»¢¤Ê¤¾¤òÆɤà¤è¤ê¡¢¼ÂºÝ¤Ë»î¤·¤Æ¤ß¤¿¤Û¤¦¤¬Ê¬¤«¤ë¤³¤È¤Ï¿¤¤¤Ç¤·¤ç¤¦¤·¤Í¡£
+¤È¤¤¤¦¤ï¤±¤Ç°§»¢¤ÏÁ᡹¤ËÀÚ¤ê¾å¤²¤ë¤³¤È¤Ë¤·¤Þ¤¹¤¬¡¢ºÇ¸å¤Ë¾¯¤·¤À¤±¡¢¸À¤ï¤»¤Æ夤¿¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
+¶äÅ·¥é¥¤¥Ö¥é¥ê¤Ï̤¤ÀȯŸÅÓ¾å¤Ë¤¢¤ë¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+¤è¤Ã¤Æºî¼Ô¤Î°Õ¿Þ¤»¤ÌÉÔ¶ñ¹ç¤ä¡¢¡Ö¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤è¡×¤È¤¤¤¦ÅÀ¤Ê¤É¡¢¤¤¤¯¤é¤Ç¤â¸ºß¤¹¤ë¤È»×¤ï¤ì¤Þ¤¹¡£
+¤½¤Î¤è¤¦¤ÊÅÀ¤ò¤â¤·¸«¤«¤±¤¿¤é¡¢µ¤¤¬¸þ¤¤¤¿¤È¤¤Ë¤Ç¤âÃΤ餻¤Æ¤â¤é¤¨¤ë¤È¡¢Èó¾ï¤Ë½õ¤«¤ë¤Î¤Ç¤¹¡£
+¶äÅ·¥é¥¤¥Ö¥é¥ê¤Î¥µ¥Ý¡¼¥È¤Ï¶äÅ·¿ïÉ®½¸ http://d.hatena.ne.jp/gintenlabo/ ¤Ç¹Ô¤Ã¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢¤â¤·µ¤¤Ë¤Ê¤ëÅÀ¤¬¤¢¤ê¤Þ¤·¤¿¤é¥³¥á¥ó¥È¤ò¤ª´ê¤¤¤·¤Þ¤¹¡£Ã±¤Ê¤ë¡Ö¤Ä¤«¤Ã¤Æ¤ß¤¿¤è¡¼¡×Ū¤Ê¥³¥á¥ó¥È¤âÂç´¿·Þ¤Ç¤¹¡£
+¤½¤ì¤Ç¤Ï¡¢¤è¤¥×¥í¥°¥é¥ß¥ó¥°¥é¥¤¥Õ¤ò¡£´ê¤ï¤¯¤Ð¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤¬¾¯¤·ÌòΩ¤Á¤Þ¤¹¤è¤¦¤Ë¡£
+
+
+¡¦¥é¥¤¥Ö¥é¥ê°ìÍ÷
+
+<gintenlib/assign.hpp>
+¥³¥Ô¡¼¤µ¤ì¤ë¦¤Î»ö¾ð¤òÍ¥À褷¤¿ std::copy ¥¢¥ë¥´¥ê¥º¥à¤ÎÊÑ·Á
+
+<gintenlib/bool_comparable.hpp>
+SafeBool ¥¤¥Ç¥£¥ª¥à¤ò´Êñ¤Ë°·¤¨¤ë¤è¤¦¤Ë¤¹¤ë¥Æ¥ó¥×¥ì¡¼¥È¥¯¥é¥¹
+
+<gintenlib/call_traits.hpp>
+¼ÂÁõÍÑ¡£ boost::call_traits ¤Ø¤Îû½Ì¥¢¥¯¥»¥¹
+
+<gintenlib/cast.hpp>
+ÌÀ¼¨Åª¤Ë°ÅÌÛÊÑ´¹¤ò¹Ô¤¦´Ø¿ô
+
+<gintenlib/clonable_ptr.hpp>
+ÊÝ»ý¤·¤¿¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀµ³Î¤ÊÊ£À½¤òºî¤ë¤³¤È¤Î¤Ç¤¤ë¡¢¶¦ÍÑ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿
+
+<gintenlib/context_error.hpp>
+ʸ̮¥¨¥é¡¼¡§ ´Ø¿ô¤Ê¤É¤ò¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¾õ¶·¤Ç¸Æ¤Ó½Ð¤·¤¿¤È¤¤ËÁ÷½Ð¤µ¤ì¤ëÎã³°
+
+<gintenlib/d_enable_if.hpp>
+enable_if ÍѤᣤ·°ú¿ô¤Ë»È¤¦·¿ dummy_arg_t ¤È¡¢dummy_arg_t ÍѤΠenable_if ¤Ç¤¢¤ë d_enable_if Åù
+
+<gintenlib/deep_ptr.hpp>
+¥³¥Ô¡¼»þ¤Ë¾ï¤Ë¿¼¤¤¥³¥Ô¡¼¤ò¹Ô¤¦¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¡£
+
+<gintenlib/deleter.hpp>
+ñ½ã¤Êºï½ü·Ï¥Õ¥¡¥ó¥¯¥¿µÍ¤á¹ç¤ï¤»
+
+<gintenlib/factorize.hpp>
+À°¿ô¤òÁÇ°ø¿ôʬ²ò¤·½ç¤Ë¥¤¥Æ¥ì¡¼¥¿¤Ë½ÐÎϤ¹¤ë´Ø¿ô factorize
+
+<gintenlib/intrusive_to_shared.hpp>
+boost::intrusive_ptr ¤ò boost::shared_ptr ¤ËÊÑ´¹¤¹¤ë¥Ä¡¼¥ë
+<gintenlib/to_shared.hpp>
+°ìÈ̤Υ¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ò boost::shared_ptr ¤ËÊÑ´¹¡Êº£¤Î¤È¤³¤í std::auto_ptr °Ê³°¤ÏÆ°ºî̤³Îǧ¡Ë
+
+<gintenlib/lexical_cast_default.hpp>
+<gintenlib/lexical_convert.hpp>
+Îã³°¤òÅꤲ¤Ê¤¤ boost::lexical_cast
+
+<gintenlib/list_format.hpp>
+¥³¥ó¥Æ¥Ê¤òÀ°·Á¤·¤Æ¥¹¥È¥ê¡¼¥à½ÐÎÏ
+<gintenlib/list_formatter.hpp>
+¥³¥ó¥Æ¥Ê¤òÀ°·Á¤·¤Æ¥¹¥È¥ê¡¼¥à½ÐÎÏ¡¢³ÈÄ¥ÈÇ
+
+<gintenlib/math.hpp>
+<cmath> ¥¤¥ó¥¯¥ë¡¼¥É¡Ü³Æ¼ïµ¹æÄê¿ô¥Þ¥¯¥í¤ÎÄêµÁ
+
+<gintenlib/move_ptr.hpp>
+std::auto_ptr ¤ÎÈù³ÈÄ¥ÈÇ¡£ swap ¤Ç¤¡¢ºï½ü´Ø¿ô¤ò»ØÄê¤Ç¤¤ë
+
+<gintenlib/new_.hpp>
+new ±é»»»Ò¤ò¸Æ¤Ó½Ð¤· shared_ptr ¤Ë³ÊǼ¤¹¤ë´Ø¿ô
+
+<gintenlib/options.hpp>
+£Ç£Î£Õ getopt() ´Ø¿ô¸ß´¹¤Î¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó²òÀÏ
+
+<gintenlib/pointer_facade.hpp>
+¤é¤¯¤Á¤ó¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¼ÂÁõ¡Ê¥Æ¥¹¥È¥³¡¼¥É¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¥Ø¥Ã¥À¤ò¸«¤ì¤Ð»È¤¤Êý¤Ïʬ¤«¤ë¤Ï¤º¤Ç¤¹¡Ë
+
+<gintenlib/preprocessor/dequote.hpp>
+typename GINTENLIB_DEQUOTE(( type )) ¤È½ñ¤¯¤³¤È¤Ç type ¤òɽ¤¹É½¸½¤Ø¤ÈŸ³«¤µ¤ì¤ë¥Þ¥¯¥í
+
+<gintenlib/preprocessor/enable_if.hpp>
+enable_if ¤òû¤¯»È¤¨¤ë¥Þ¥¯¥í GINTENLIB_ENABLE_IF(( cond )) Åù
+
+<gintenlib/reference_counter.hpp>
+boost::intrusive_ptr ÍѤλ²¾È¥«¥¦¥ó¥¿ÉÕ¤¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ½ºîÊä½õ
+
+<gintenlib/to_string.hpp>
+Ǥ°Õ¤Îɽ¸½¤òʸ»úÎó¤ËÊÑ´¹
+
+<gintenlib/typed_saver.hpp>
+<gintenlib/value_saver.hpp>
+¥Ç¥¹¥È¥é¥¯¥¿¤ÇÊÑ¿ô¤ÎÃͤò´¬¤Ì᤹¥¯¥é¥¹
+
+<gintenlib/enable_if.hpp>
+<gintenlib/ignore.hpp>
+<gintenlib/shared_ptr.hpp>
+<gintenlib/type.hpp>
+<gintenlib/tribool.hpp>
+ñ¤Ê¤ë boost ¤Ø¤Î using Àë¸À
+
+
+¡¦¥¤¥ó¥¹¥È¡¼¥ë¤Ë¤Ä¤¤¤Æ
+
+¶äÅ·¥é¥¤¥Ö¥é¥ê¤Ï¥Ø¥Ã¥À¤Î¤ß¤Ç¹½À®¤µ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+
+¡¦¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¡Ê¤³¤Î¥Õ¥¡¥¤¥ë¤¬¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¡Ë¤Ë¥¤¥ó¥¯¥ë¡¼¥É¥Ñ¥¹¤òÄ̤¹¡Ê¿ä¾©¡Ë
+¡¦´û¸¤Î¥¤¥ó¥¯¥ë¡¼¥ÉÍѥǥ£¥ì¥¯¥È¥ê¤Ë¥é¥¤¥Ö¥é¥ê¤Î¥Ç¥£¥ì¥¯¥È¥ê¡Ê¤³¤Î¥Õ¥¡¥¤¥ë¤ÈƱ³¬Áؤˤ¢¤ë gintenlib/ ¡Ë¤ò¥³¥Ô¡¼¤¹¤ë
+¡¦¶äÅ·¥é¥¤¥Ö¥é¥ê¤ò»È¤¤¤¿¤¤¥×¥í¥°¥é¥à¤Î¤¢¤ë¾ì½ê¤Ë¥é¥¤¥Ö¥é¥ê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¥³¥Ô¡¼¤¹¤ë¡ÊÈó¿ä¾©¡Ë
+
+¤³¤È¤Ë¤è¤ê¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+
+¡¦¡¦¡¦¤È¡¢¤½¤ÎÁ°¤Ë¡£
+¶äÅ·¥é¥¤¥Ö¥é¥ê¤Ï Boost C++ Libraries ( http://www.boost.org/ ) ¤òÍѤ¤¤ÆºîÀ®¤µ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤Ê¤Î¤Ç¡¢¤½¤Î»ÈÍѤˤÏͽ¤á Boost ¤ò¡Ê ver1.40.0 °Ê¹ß¡Ë¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£¾Ü¤·¤¤ÊýË¡¤Ï Boost ËܲȤ«¡¢±Ñ¸ì¤¬¶ì¼ê¤Ê¾ì¹ç¤Ë¤Ï Let's Boost ( http://www.kmonos.net/alang/boost/ ) ¤ò»²¾È¤¹¤ë¤È¤è¤¤¤Ç¤·¤ç¤¦¡£
+Boost ¤ÏÊØÍø¤Ê¥é¥¤¥Ö¥é¥ê¤Ê¤Î¤Ç¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Ê¤¤¾ì¹ç¤Ç¤â¥ª¥¹¥¹¥á¤Ç¤¹¡£
+
+
+¡¦¥é¥¤¥»¥ó¥¹¤Ë¤Ä¤¤¤Æ
+
+LICENSE ¥Õ¥¡¥¤¥ë¤Ë¤Þ¤È¤á¤Æ¤¢¤ê¤Þ¤¹¡£´Êñ¤Ë¸À¤¦¤È zlib/libpng ¥é¥¤¥»¥ó¥¹¤Ç¤¹¡£
+½ÐÍè¤ë¸Â¤ê¿¤¯¤Î¿Í¤Ë»È¤Ã¤Æ¤â¤é¤¦¤¿¤á¡¢Èó¾ï¤Ë¤æ¤ë¤¤¥é¥¤¥»¥ó¥¹¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+¤¹¤Ê¤ï¤Á¡¢»ÈÍѤϻäÍѾ¦ÍѤòÌä¤ï¤º¼«Í³¡¢²þÊѤäºÆÇÛÉۤ⤽¤Î»Ý¤òÌÀµ¤¹¤ì¤Ð¼«Í³¡¢ºî¤Ã¤¿¥×¥í¥°¥é¥à¤Î README ¤Ë¡Ö¶äÅ·¥é¥¤¥Ö¥é¥ê»È¤Ã¤¿¤è¡×¤È½ñ¤¯É¬Íפ⤢¤ê¤Þ¤»¤ó¡Ê½ñ¤¤¤Æ¤â¤é¤¨¤ë¤È´î¤Ó¤Þ¤¹¤¬¡Ë¡£
+¤È¤¤¤¦¤«¥³¡¼¥ÉÊÒ¤òÍøÍѤ¹¤ëÄøÅ٤Ǥ¢¤ì¤Ð¡¢¥½¡¼¥¹¥³¡¼¥ÉÆâ¤Ç¤¢¤Ã¤Æ¤â¡Ö¤³¤ì¤Ï¶äÅ·¥é¥¤¥Ö¥é¥ê¤Ë½ñ¤¤¤Æ¤¢¤Ã¤¿¤è¡×¤Ê¤ó¤Æ¸ÀµÚ¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡Ê´Ø¿ô´Ý¤´¤È¥³¥Ô¥Ú¤¹¤ë¥ì¥Ù¥ë¤À¤ÈήÀФ˽ñ¤¤¤ÆÍߤ·¤¤¤Ç¤¹¤¬¡Ë¡£
+¤É¤¦¤¾¤ªµ¤·Ú¤Ë»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+
+¡¦º¤¤Ã¤¿¤³¤È¤¬¤¢¤Ã¤¿¤é
+
+¶äÅ·¿ïÉ®½¸ http://d.hatena.ne.jp/gintenlabo/ ¤Þ¤Ç¥¢¥¯¥»¥¹¤ò¤ª´ê¤¤¤·¤Þ¤¹¡£ wiki ¤È¤«¤Ï¼ûÍפ¬¤¢¤Ã¤¿¤éºî¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+¤¢¤ë¤¤¤Ï¡¢¤Ä¤¤¤Ã¤¿¡¼ http://twitter.com/ ¤Ç #gintenlib ¤ò¤Ä¤±¤ÆÒ줯¤È¤«¡£³ä¤ÈÉÑÈˤ˥Á¥§¥Ã¥¯¤¹¤ëͽÄê¤Ê¤Î¤Ç¿ʬµ¤¤Å¤¯¤È»×¤¤¤Þ¤¹¡£
+
+
+¡¦º¤¤Ã¤¿¤³¤È¤¬Ìµ¤±¤ì¤Ð
+
+¤Ê¤¯¤Æ¤â¤¤¤¤¥é¥¤¥Ö¥é¥ê¤À¤±¤É¡¢»î¤·¤Ë»È¤Ã¤Æ¤ß¤ë¤È¡¢¾¯¤·¤ÏÊØÍø¤«¤â¤·¤ì¤Þ¤»¤ó¤è¡©
+
+
+¡¦¹¹¿·ÍúÎò
+2009/12/09 ½éÈÇ
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_ASSIGN_HPP_
+#define GINTENLIB_INCLUDED_ASSIGN_HPP_
+
+/*
+
+ <gintenlib/assign.hpp>
+
+ assign ¡§ ¥³¥Ô¡¼¤µ¤ì¤ë¦¤ÎÅÔ¹ç¤òÍ¥À褹¤ë copy ¥¢¥ë¥´¥ê¥º¥à
+
+ Àë¸À¡§
+ template< typename FwdOutIte, typename InIte >
+ InIte assign( FwdOutIte begin, FwdOutIte end, InIte src );
+
+ template< typename Range, typename InIte >
+ InIte assign( Range& dest, InIte src );
+
+ µ¡Ç½¡§
+ [ begin, end ) ¶è´Ö¡¢¤¢¤ë¤¤¤Ï¶è´Ö dest ¤ò¡¢¥¤¥Æ¥ì¡¼¥¿ src ¤Ë¤è¤Ã¤Æ½é´ü²½¤·¤Þ¤¹¡£
+ Ìá¤êÃͤϺǸå¤ËÂåÆþ¤·¤¿ src ¤Î¼¡¤ÎÍ×ÁǤò¼¨¤¹¥¤¥Æ¥ì¡¼¥¿¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ Åù²Á¥³¡¼¥É¡§
+ // ¥¤¥Æ¥ì¡¼¥¿ÈǤΤߵ½Ò
+ for( FwdOutIte ite = begin; ite != end; ++ite, ++src )
+ {
+ *ite = *src;
+ }
+
+ »ÈÍÑÎ㡧
+ int a[10];
+ boost::array<int, 10> b;
+
+ // a ¤ò¡¢boost::counting_iterator ¤ò»È¤¤ 1 ¡Á 10 ¤ÎÃͤǽé´ü²½
+ gintenlib::assign( a, boost::counting_iterator<int>(1) );
+
+ // b ¤òµÕ½ç¤Ë a ¤Ç½é´ü²½
+ gintenlib::assign( b.rbegin(), b.rend(), &a[0] );
+
+ // ɽ¼¨
+ cout << gintenlib::list_format( a ) << endl;
+ cout << gintenlib::list_format( b ) << endl;
+
+ Ê䡧
+ ¡¦¼ç¤Ë¸ÇÄêĹ¤Î¥³¥ó¥Æ¥Ê¤ò½é´ü²½¤ò¤¹¤ë¾ìÌ̤òÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£
+ ¡¦²ÄÊÑĹ¤Î¥³¥ó¥Æ¥Ê¤Î¾ì¹ç¤Ï¡¢insert_iterator ¤ò»È¤Ã¤Æ copy ¤·¤¿Êý¤¬¸ú²ÌŪ¤Ç¤¹¡£
+
+*/
+
+#include <boost/range.hpp>
+
+namespace gintenlib
+{
+ // [ begin, end ) ¶è´Ö¤ò src ¤Ç½é´ü²½
+ template< typename FwdOutIte, typename InIte >
+ inline InIte assign( FwdOutIte begin, FwdOutIte end, InIte src )
+ {
+ while( begin != end )
+ {
+ *begin = *src;
+ ++begin; ++src;
+ }
+ return src;
+ }
+
+ // dest ¤ò src ¤Ç½é´ü²½
+ template< typename Range, typename InIte >
+ inline InIte assign( Range& dest, const InIte& src )
+ {
+ return ::gintenlib::assign( boost::begin(dest), boost::end(dest), src );
+ }
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_ASSIGN_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_
+#define GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_
+
+/*
+ bool_comparable : safe_bool¥¤¥Ç¥£¥ª¥àÄó¶¡
+
+ Àë¸À¡§
+ template<typename Derived>
+ class bool_comparable
+ {
+ public:
+ // safe_bool ËÜÂÎ
+ operator unspecified_bool_type() const;
+ // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤Î¦¤Ç operator! ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢
+ // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤Î boolean_test() ¥á¥ó¥Ð´Ø¿ô¤¬¤¢¤ì¤Ð¤½¤ÎÈÝÄê¤òÊÖ¤¹¡£
+ // operator!() ¤â boolean_test() ¤â¤Ê¤±¤ì¤Ð¡¢¥¨¥é¡¼
+ bool operator!() const;
+
+ // bool ¤È¤ÎÈæ³Ó¡£ int ¤Î¤È¤¤ÏÈ¿±þ¤·¤Ê¤¤¤è¤¦¤Ë¤Ê¤Ã¤Æ¤Þ¤¹
+ friend bool operator==( const bool_comparable& lhs, bool rhs );
+ friend bool operator==( bool lhs, const bool_comparable& rhs );
+ friend bool operator!=( const bool_comparable& lhs, bool rhs );
+ friend bool operator!=( bool lhs, const bool_comparable& rhs );
+
+ protected:
+ bool_comparable() {}
+ ~bool_comparable() {}
+
+ }; // class bool_comparable<Derived>
+
+
+ // ¾¡¢¸Æ¤Ó½Ð¤µ¤ì¤ë¤È¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤Ë¤Ê¤ë operator== ¤È operator!= ¤¬Àë¸À¤µ¤ì¤Æ¤¤¤Þ¤¹
+
+ µ¡Ç½¡§
+ boost::operators ¤ß¤¿¤¤¤Ê´¶¤¸¤Ë¡¢´Êñ¤Ë safe_bool ¥¤¥Ç¥£¥ª¥à¤ò¼Â¸½¤·¤Þ¤¹¡£
+ »ÈÍÑË¡¤Ï¡¢bool_comparable ¤Î¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤ËÀ½ºî¤¹¤ë¥¯¥é¥¹¤Î̾Á°¤òÆþ¤ì¤Æ public ·Ñ¾µ¡£
+ ¤½¤·¤ÆÀ½ºî¤¹¤ë¥¯¥é¥¹¤Ë¡¢
+ bool operator!() const;
+ ´Ø¿ô¤«¡¢¤¢¤ë¤¤¤Ï
+ bool boolean_test() const;
+ ´Ø¿ô¤Î¤É¤Á¤é¤«¤òÄêµÁ¤¹¤ì¤Ð£Ï£Ë¤Ç¤¹¡ÊξÊý¤¢¤ë¾ì¹ç¤Ï operator!() ¤¬Í¥À褵¤ì¤Þ¤¹¡Ë¡£
+
+ »ÈÍÑË¡ :
+ // Îã¤È¤·¤Æ boost::optional Ū¤Ê²¿¤«¤òºî¤ê¤Þ¤·¤ç¤¦
+ #include <boost/scoped_ptr.hpp>
+
+ template<typename T>
+ class my_optional
+ : public gintenlib::bool_comparable< my_optional<T> > // ¤³¤Î¤è¤¦¤Ë»È¤¦
+ {
+ // ËÜÂÎÉôʬ¤Ï¤Ê¤ó¤éµ¤¤Ë¤»¤º½ñ¤¤¤Æ¤è¤¤
+ public:
+ typedef T value_type;
+
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ my_optional() : p() {}
+ my_optional( const T& x ) : p( new T(x) ) {}
+
+ reference operator*() { return *p; }
+ const_reference operator*() const { return *p; }
+
+ // operator!() ¤ò³Î¼Â¤Ë¼ÂÁõ¤¹¤ë¤³¤È¤ò˺¤ì¤Ê¤±¤ì¤Ð¡£
+ bool operator!() const
+ {
+ return !p;
+ }
+ // ¤³¤ì¤Ë¤è¤ê¡¢boolÈæ³Ó¤â½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ë
+
+ // ¤Á¤Ê¤ß¤Ë operator!() ¤¸¤ã¤Ê¤¯¤Æ
+ // bool boolean_test() const { return p.get(); }
+ // ¤³¤ì¤Ç¤â¤¤¤¤¡Ê¤½¤Î¾ì¹ç¡¢operator! ¤Ï¼«Æ°ÄêµÁ¡Ë
+
+ // ¤½¤Î¤Û¤«¡¢¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤È¤«ÂåÆþ±é»»»Ò¤È¤«¤ÏÌÌÅݤÀ¤«¤é¾Êά
+
+ private:
+ // ÌÌÅݤʥݥ¤¥ó¥¿´ÉÍý¤È¤«¤·¤¿¤¯¤Ê¤¤¤Î¤Ç scoped_ptr ¤ò»È¤¦
+ boost::scoped_ptr<T> p;
+
+ };
+
+ int main()
+ {
+ my_optional<int> a, b(1), c(0);
+
+ // if ¤Î¾ò·ïÉô¤È¤·¤Æ
+ if( a )
+ {
+ assert( !"a is empty." );
+ }
+
+ // && ¤ä || ¤ÈÁȤ߹ç¤ï¤»¤Æ
+ assert( b && c );
+
+ // ¥¼¥í¤È¤ÎÈæ³Ó
+ assert( a == 0 && b != 0 && c != 0 );
+ // assert( b == 1 ); // 1 ¤È¤ÏÈæ³Ó¤Ç¤¤Ê¤¤
+
+ // bool ÃͤȤÎÈæ³Ó
+ assert( a == false && b == true && c == true );
+ // static_cast
+ assert( static_cast<bool>(b) == static_cast<bool>(c) );
+ // assert( a != b ); // ¥³¥ì¤Ï¥À¥á¡Ê¤â¤· b ¤È c ¤òÈæ³Ó¤·¤¿¤é¡©¡Ë
+
+ Ãí°Õ»ö¹à¡§
+ ¡¦boost::enable_if ¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£¸Å¤¤¥³¥ó¥Ñ¥¤¥é¤Ç¤ÏÆ°¤¤Þ¤»¤ó¡£
+ ¡¦¤½¤ì¤¬·ù¤Ê¤é GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF ¥Þ¥¯¥í¤òÄêµÁ¤¹¤ì¤Ð£Ï£Ë¤Ç¤¹¡£
+ ¡¦¤¿¤À¤·¡¢¤½¤Î¾ì¹ç¡¢¾å¤ÎÎã¤Ç¤Î¡Öb == 1¡×Ū¤Êɽ¸½¤¬¥³¥ó¥Ñ¥¤¥ëÄ̤äƤ·¤Þ¤¤¤Þ¤¹¡£
+
+ ¡¦¡Ö a == b ¡×¤Î¤è¤¦¤Ê¡¢ÇÉÀ¸Àè¤Î¥¯¥é¥¹Æ±»Î¤Ç¤ÎÈæ³Ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤Ë¤Ê¤ê¤Þ¤¹¡£
+ ¡¦¤Ç¤¹¤¬¡¢ÅöÁ³¡¢ÇÉÀ¸Àè¤Ç operator== ¤òÄêµÁ¤·¤Æ¤ª¤±¤Ð¡¢¤¤Á¤ó¤ÈÈæ³Ó¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+ ¡¦¤¿¤À¤·¡¢ÇÉÀ¸Àè¤Î¥¯¥é¥¹¤¬¡Ö 0 ¤«¤é°ÅÌÛÊÑ´¹²Äǽ¡×¤Ç¤¢¤ê¡Öoperator==¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡×¾ì¹ç¤Ï¡¢
+ ¡Ö x == 0 ¡×¤Î¤è¤¦¤ÊÈæ³Ó¤¬¡¢¥¼¥í¤È¤ÎÈæ³Ó¤Ë¸Â¤ê¤Ç¤¹¤¬¡¢½ÐÍè¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹:
+ struct convertible_from_int
+ : gintenlib::bool_comparable<convertible_from_int>,
+ private boost::equality_comparable<convertible_from_int>
+ {
+ int value;
+ convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
+
+ bool operator!() const { return value == 0; }
+
+ // operator== ¤Ë¤è¤ëÈæ³Ó¤¬½ÐÍè¤ë¾ì¹ç
+ friend bool operator==( const convertible_from_int& lhs, const convertible_from_int& rhs )
+ {
+ return lhs.value == rhs.value;
+ }
+
+ };
+
+ int main()
+ {
+ convertible_from_int x, y = 2;
+ assert( !x ); // ¤³¤¦¤¤¤¦¤Î¤ÏÉáÄ̤˽ÐÍè¤ë¤¬
+ assert( y );
+ assert( x == false );
+ assert( y == true );
+
+ // assert( x == 0 ); // ¥³¥ì¤¬¼Â¹Ô¤Ç¤¤Ê¤¤¡ÊÛ£Ëæ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡Ë
+ // assert( y != 0 ); // ÅöÁ³¤³¤ì¤â¥À¥á
+
+ assert( y == 2 ); // ¤Ç¤â¥³¥ì¤Ï£Ï£Ë
+ assert( x != 1 ); // ¥³¥ì¤â£Ï£Ë
+ }
+
+ ¡¦¤½¤Î¾ì¹ç¤Ï int ¤È¤ÎÈæ³Ó¤òÊ̸ÄÄêµÁ¤·¤Æ¤ä¤ì¤Ð£Ï£Ë¤Ç¤¹¡§
+ struct convertible_from_int
+ : gintenlib::bool_comparable<convertible_from_int>,
+ private boost::equality_comparable<convertible_from_int>,
+ private boost::equality_comparable<convertible_from_int, int>
+ {
+ int value;
+ convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¾ì¹ç¤Ç¤â
+
+ bool boolean_test() const { return value; } // boolean_test ¤ò»È¤Ã¤Æ¤ß¤ë¡£
+
+ friend bool operator==( const piyo& lhs, const piyo& rhs )
+ {
+ return lhs.value == rhs.value;
+ }
+ // int ¤È¤ÎÈæ³Ó¤òÌÀ¼¨Åª¤ËÄêµÁ¤µ¤¨¤¹¤ì¤Ð
+ friend bool operator==( const convertible_from_int& lhs, int rhs )
+ {
+ return lhs.value == rhs;
+ }
+
+ };
+
+ int main()
+ {
+ convertible_from_int x, y(2)
+ assert( x == 0 ); // £Ï£Ë
+ assert( y != 0 );
+ }
+
+*/
+
+#ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
+ #include "enable_if.hpp"
+ #include <boost/type_traits/is_same.hpp>
+#endif
+
+namespace gintenlib
+{
+ // ¥Ø¥ë¥Ñ¹½Â¤ÂÎ
+ struct bool_comparable_helper
+ {
+ // operator bool_type() ¤ÎÌá¤êÃͤȤ·¤Æ»È¤ï¤ì¤ëÃÍ
+ void bool_value() const {}
+
+ private:
+ // ¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤òµ¯¤³¤¹¤¿¤á¤Î private ´Ø¿ô
+ bool this_type_does_not_support_comparisons_();
+
+ };
+
+ // ËÜÂÎ
+ template<typename Derived>
+ class bool_comparable
+ {
+ // safe-bool ¤Ë»È¤¦·¿¡Ê¥á¥ó¥Ð´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¡Ë
+ typedef void (bool_comparable::*bool_type)() const;
+
+ // ÇÉÀ¸¤·¤¿¥¯¥é¥¹¤òÆÀ¤ë´Ø¿ô
+ const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ Derived& derived() { return *static_cast< Derived*>(this); }
+
+ // ¾¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤â derived ¤Ï»È¤¤¤¿¤¤¤¼
+ template<typename U> friend class bool_comparable;
+
+ public:
+ // ËÜÂê
+ operator bool_type() const
+ {
+ return bool_test_() ? bool_value_() : 0;
+ // bool_test_, bool_value_ ¤Ï¸å¤ÇÄêµÁ¤¹¤ë
+ }
+
+ // bool ¤È¤ÎÈæ³Ó
+
+ #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
+
+ // enable_if ¤Ç bool ¤ÈÈæ³Ó¤¹¤ë»þ¤À¤±Í¸ú¤Ë¤¹¤ë¤³¤È¤Ç¡¢x == 1 ¤Î¤è¤¦¤ÊÈæ³Ó¤ò̵Îϲ½¤¹¤ë
+ // todo: g++ °Ê³°¤Î¥³¥ó¥Ñ¥¤¥é¤Ç¤ÎÆ°ºî¥Á¥§¥Ã¥¯
+
+ // ¼ÂÁõ
+ template<typename U>
+ friend typename enable_if<boost::is_same<U, bool>, bool>::type
+ operator==( const Derived& lhs, U rhs )
+ {
+ return static_cast<bool>(lhs) == rhs;
+ }
+ template<typename U>
+ friend typename enable_if<boost::is_same<U, bool>, bool>::type
+ operator==( U lhs, const Derived& rhs )
+ {
+ return lhs == static_cast<bool>(rhs);
+ }
+ template<typename U>
+ friend typename enable_if<boost::is_same<U, bool>, bool>::type
+ operator!=( const Derived& lhs, U rhs )
+ {
+ return static_cast<bool>(lhs) != rhs;
+ }
+ template<typename U>
+ friend typename enable_if<boost::is_same<U, bool>, bool>::type
+ operator!=( U lhs, const Derived& rhs )
+ {
+ return lhs != static_cast<bool>(rhs);
+ }
+
+ #else // #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
+
+ // °ì±þ enable_if ¤ò»È¤ï¤Ê¤¤ÈǤâÍÑ°Õ
+ // ¤³¤Î¾ì¹ç¡¢ x == 1 ¤Î¤è¤¦¤Êɽ¸½¤¬Ä̤äƤ·¤Þ¤¦¤¬»ÅÊý¤Ê¤¤¤Í
+ friend bool operator==( const Derived& lhs, bool rhs )
+ {
+ return static_cast<bool>(lhs) == rhs;
+ }
+ friend bool operator==( bool lhs, const Derived& rhs )
+ {
+ return lhs == static_cast<bool>(rhs);
+ }
+ friend bool operator!=( const Derived& lhs, bool rhs )
+ {
+ return static_cast<bool>(lhs) != rhs;
+ }
+ friend bool operator!=( bool lhs, const Derived& rhs )
+ {
+ return lhs != static_cast<bool>(rhs);
+ }
+
+ #endif // #ifndef GINTENLIB_BOOL_COMPARABLE_NO_ENABLE_IF
+
+ private:
+ // ¼ÂÁõÊä½õ
+ // bool_type ¤È¤·¤ÆÊÖ¤¹ÃÍ
+ static bool_type bool_value_()
+ {
+ // ´Ø¿ô¤ò̵Â̤˺î¤é¤»¤Ê¤¤¹©Éס£¤É¤¦¤» bool_type ¤ÎÃͤϻȤï¤Ê¤¤¤·
+ return reinterpret_cast<bool_type>( &bool_comparable_helper::bool_value );
+ }
+
+ // ¥Æ¥¹¥È´Ø¿ô
+ // ¤Þ¤º Derived::operator!() ¤ò¸«¤Ë¹Ô¤¯
+ bool bool_test_() const
+ {
+ return !( !derived() );
+ }
+
+ public:
+ // Derived ¦¤Ç operator!() ¤¬ÄêµÁ¤µ¤ì¤Æ̵¤¤¤Ê¤é
+ // Derived::boolean_test() ´Ø¿ô¤¬¤Ê¤¤¤«Ãµ¤·¡¢Ìµ¤±¤ì¤Ð¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼
+ bool operator!() const
+ {
+ return !( derived().boolean_test() );
+ }
+ // friend ´Ø¿ôÈÇ¡£Â¸ºß¤¹¤ë°ÕÌ£¤ÏÆäË̵¤¤¡£
+ friend bool boolean_test( const bool_comparable& x )
+ {
+ return x.bool_test_();
+ }
+
+ // Èæ³Ó¤Ï¥¨¥é¡¼¤Ë¤Ê¤ë¡Ê Derived ¦¤ÇÆÃÊ̤ËÄêµÁ¤¹¤ì¤Ð£Ï£Ë¡Ë
+
+ // ÅùÃÍÈæ³Ó
+ friend bool operator==( const bool_comparable& lhs, const bool_comparable& rhs )
+ {
+ return bool_comparable_helper().this_type_does_not_support_comparisons_();
+ }
+ // ÉÔÅùÃÍÈæ³Ó
+ friend bool operator!=( const bool_comparable& lhs, const bool_comparable& rhs )
+ {
+ return bool_comparable_helper().this_type_does_not_support_comparisons_();
+ }
+
+ protected:
+ // ÇÉÀ¸¥¯¥é¥¹°Ê³°¤«¤é¤Î¹½Ã۶ػß
+ bool_comparable() {}
+ ~bool_comparable() {}
+
+ }; // class bool_comparable<Derived>
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_BOOL_COMPARABLE_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_CALL_TRAITS_HPP_
+#define GINTENLIB_INCLUDED_CALL_TRAITS_HPP_
+
+/*
+
+ <gintenlib/call_traits.hpp>
+
+ call_traits ¡§ boost::call_traits ¡Ü¦Á
+
+ Àë¸À¡§
+ template<typename T>
+ struct call_traits
+ : boost::call_traits<T>
+ {
+ typedef T type;
+ };
+
+ µ¡Ç½¡§
+ boost::call_traits ¤Ë¡ÖÍ¿¤¨¤é¤ì¤¿·¿¤ò¤½¤Î¤Þ¤ÞÊÖ¤¹¡×¥á¥¿´Ø¿ô¤Îµ¡Ç½¤ò²Ã¤¨¤¿¤â¤Î¤Ç¤¹¡£
+ reference ¤ä param_type ¤Î¼èÆÀ¤â¤·¤¿¤¤¤·¡¢¥á¥¿´Ø¿ô¤È¤·¤Æ¤â»È¤¤¤¿¤¤¡¢¤Ê¤ó¤Æ¶ÉÌ̤ǻȤ¤¤Þ¤¹¡£
+ ñ½ã¤Ë boost::call_traits ¤Ï gintenlib Æâ¤Ç¤Î»ÈÍѤ¬Â¿¤¤¤Î¤Ç¡¢Ã»½Ì¤È¤·¤Æ»È¤¦°ÕÌ£¤â¤¢¤ê¤Þ¤¹¡£
+
+*/
+
+#include <boost/call_traits.hpp>
+
+namespace gintenlib
+{
+ // typename call_traits<T>::type ¤Ï T ¤ËÅù¤·¤¤
+ template<typename T>
+ struct call_traits
+ : boost::call_traits<T>
+ {
+ typedef T type;
+ };
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_CALL_TRAITS_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_CAST_HPP_
+#define GINTENLIB_INCLUDED_CAST_HPP_
+
+/*
+
+ <gintenlib/cast.hpp>
+
+ cast ¡§ ÌÀ¼¨Åª¤Ê°ÅÌÛ¥¥ã¥¹¥È
+
+ Àë¸À¡õÄêµÁ¡§
+ // °ú¿ô¤ò¤½¤Î¤Þ¤ÞÊÖ¤¹
+ template<typename T>
+ inline T cast( typename boost::call_traits<T>::param_type x ) { return x; }
+
+ µ¡Ç½¡§
+ °ÅÌÛÊÑ´¹¤òÌÀ¼¨Åª¤Ë¹Ô¤¦¤¿¤á¤Î¥¥ã¥¹¥È¤Ç¤¹¡£ cast<void*>( 0 ) ¤Î¤è¤¦¤Ë»È¤¤¤Þ¤¹¡£
+ ¼ç¤Ë¿½ÅÄêµÁ¤µ¤ì¤¿´Ø¿ô¤Î¸Æ¤Ó½Ð¤·¤òÀ©¸æ¤¹¤ë¤È¤¤Ë»È¤¤¤Þ¤¹¡£
+
+ »ÈÍÑÎ㡧
+ void hoge( int ){ cout << "int ÈǤǤ¹\n"; }
+ void hoge( void* ){ cout << "void* ÈǤǤ¹\n"; }
+
+ // ¥¯¥é¥¹¤ËÂФ·¤Æ
+ // noncopyable ¤Ê¥¯¥é¥¹¤Ë¤·¤Æ¤ª¤¯
+ class base : boost::noncopyable {};
+ struct derived : base {};
+
+ void fuga( base& ){ cout << "base& ÈǤǤ¹\n"; }
+ void fuga( derived& ){ cout << "derived& ÈǤǤ¹\n"; }
+
+ int main()
+ {
+ // ͽ¤á using Àë¸À¤¹¤ì¤Ð»Íʸ»ú¤Ç»È¤¨¤Æ¹¬¤»
+ using gintenlib::cast;
+
+ hoge( 0 ); // int ÈÇ
+ hoge( cast<void*>(0) ); // void* ÈÇ¡£static_cast<void*>(0) ¤Ç¤â£Ï£Ë¤À¤¬Ä¹¤¤
+
+ derived x; // ¤¢¤ë¤¤¤Ï base x;
+ fuga( x ); // ¥Ç¥Õ¥©¥ë¥È¸Æ¤Ó½Ð¤·
+ fuga( cast<base&>(x) ); // base& ÈÇ¡£
+ fuga( cast<derived&>(x) ); // derived& ÈÇ¡£base x; ¤Î¾ì¹ç¤Ï¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼
+ // static_cast ¤À¤È¡¢¥³¥ó¥Ñ¥¤¥ë¥¨¥é¡¼¤Ë¤Ê¤é¤Ê¤¤
+ }
+
+ Ê䡧
+ ¡¦°ÅÌÛÊÑ´¹¤òÌÀ¼¨Åª¤Ë¤ä¤Ã¤Æ²¿¤¬³Ú¤·¤¤¤«¤È¤¤¤¨¤Ð¡¦¡¦¡¦»ÈÍÑÎã¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤¬Á´¤Æ¤Ç¤¹¡£
+ ¡¦¤³¤Î¤è¤¦¤Ë¡¢´Ø¿ô¤Î¿½ÅÄêµÁ¤ä¥Æ¥ó¥×¥ì¡¼¥È¤ËÂФ·¡¢Àµ¤·¤¤¤â¤Î¤ò»ØÄꤹ¤ë¤È¤¤Ë»È¤¨¤Þ¤¹¡£
+ ¡¦static_cast ¤È¤Î°ã¤¤¤Ï¡¢ Source ¤Î·¿¤¬°ÅÌÛŪ¤Ë Target ¤ËÊÑ´¹¤Ç¤¤ë»þ¤À¤±¥¥ã¥¹¥È¤Ç¤¤ëÅÀ¡£
+ ¡¦¤Þ¤¡ÉáÄÌ¤Ï static_cast ¤Ç¤â½½Ê¬¤Ê¤ó¤Ç¤¹¤¬¡¢¥¯¥é¥¹¤Î·Ñ¾µ¤È¤«¤ò»È¤¦¤È¡¢¤ä¤Ã¤Ñ¤ê´í¸±¤Ê¤Î¤Ç¡£
+ ¡¦¾¯¤·Á°¤Þ¤Ç¤Î¼ÂÁõ¤Ï boost::enable_if ¤ò»È¤Ã¤Æ¤¤¤Þ¤·¤¿¤¬¡¢½¤Àµ¤µ¤ì¤Þ¤·¤¿¡£
+ ¡¦boost::call_traits ¤µ¤¨Æ°¤±¤ÐÆ°¤¤Þ¤¹¡£
+
+*/
+
+#include <boost/call_traits.hpp>
+
+namespace gintenlib
+{
+ // °ÅÌÛ¥¥ã¥¹¥È´Ø¿ô
+ template<typename T>
+ inline T cast( typename boost::call_traits<T>::param_type x )
+ {
+ return x;
+ }
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_CAST_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_CLONABLE_PTR_HPP_
+#define GINTENLIB_INCLUDED_CLONABLE_PTR_HPP_
+
+/*
+
+ <gintenlib/clonable_ptr.hpp>
+
+ clonable_ptr ¡§ ¿¼¤¤¥³¥Ô¡¼¤¬²Äǽ¤Ê»²¾È¥«¥¦¥ó¥È¼°¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿
+
+ Àë¸À¡§
+ template<typename T>
+ struct clonable_ptr
+ {
+ // ´ðËÜŪ¤Ê¥á¥½¥Ã¥É¤Ï¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ÈƱ¤¸¤Ê¤Î¤Ç¾Êά
+
+ // »²¾È¥«¥¦¥ó¥È¤Î¿ô¤òÊÖ¤¹
+ int use_count() const;
+ // »²¾È¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤¬¡¢¤³¤Î¥Ý¥¤¥ó¥¿¤Î¤ß¤«¤é»²¾È¤µ¤ì¤Æ¤¤¤ë¾ì¹ç true
+ bool unique() const;
+
+ // ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÊ£À½¤òºî¤ê½Ð¤·¤ÆÊÖ¤¹
+ clonable_ptr<typename boost::remove_const<T>::type> clone() const;
+ // unique ¤Ç¤Ê¤±¤ì¤Ð»²¾È¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÊ£À½¤·¤Æ unique ¤Ë¤¹¤ë
+ void to_unique();
+
+ // boost::shared_ptr ¤Ø¤ÎÊÑ´¹
+ boost::shared_ptr<T> to_shared() const;
+ friend boost::shared_ptr<T> to_shared( const clonable_ptr& target );
+
+ // ¤½¤Î¤Û¤«¡¢xxx_pointer_cast ·Ï¤Î´Ø¿ô¤â¤¢¤ë
+
+ };
+
+ µ¡Ç½¡§
+ ÂоݤΡֿ¼¤¤¥³¥Ô¡¼¡×¤òÀ¸À®¤Ç¤¤ë»²¾È¥«¥¦¥ó¥È¼°¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¡£
+ ¼ç¤ËÂоݤη¿¤òÀµ³Î¤Ëµ²±¤·Ê£À½¤¹¤ëÄøÅ٤ε¡Ç½¤ò»ý¤Á¤Þ¤¹¡£
+ ÆäËÊØÍø¤Ê¤Î¤¬ to_unique ¥á¥ó¥Ð´Ø¿ô¤Ç¡¢¤³¤Î¥Ý¥¤¥ó¥¿¤Î¸ºßÍýͳ¤ÎÂçȾ¤¬¤³¤ì¤Ë½¸Ì󤵤ì¤Þ¤¹¡£
+ ¥³¥Ô¡¼¤Ë¥³¥¹¥È¤Î¤«¤«¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ò°·¤¦¤È¤¡¢ÉáÃʤÏÀõ¤¤¥³¥Ô¡¼¤Ç¥³¥Ô¡¼¥³¥¹¥È¤òºï¸º¡¢
+ ¥ª¥Ö¥¸¥§¥¯¥È¤ËÊѹ¹¤ò²Ã¤¨¤ë¤È¤¤Ï¤½¤ÎÁ°¤Ë to_unique ¤ò¸Æ¤Ó½Ð¤¹¡¢¤Ê¤ó¤Æ»È¤¤Êý¤¬°ìÈÌŪ¤«¤È¡£
+ ¤â¤Á¤í¤ó¡¢¡ÖÂоݤΥª¥Ö¥¸¥§¥¯¥È¤ÎÀµ³Î¤Ê¥³¥Ô¡¼¤òºî¤ì¤ë¡×¤È¤¤¤¦ÅÀ¤ËÃåÌܤ·¤¿»È¤¤Êý¤â¥¢¥ê¤Ç¤¹¡£
+ ¹âµ¡Ç½¤Ç¤¹¤¬¡¢¥³¥Ô¡¼ÉÔǽ¤Ê¥ª¥Ö¥¸¥§¥¯¥È¤Ï¤½¤â¤½¤â³ÊǼ¤Ç¤¤Ê¤¤¤Î¤Ç¡¢¤½¤³¤À¤±¤ÏÃí°Õ¤¬É¬Íס£
+ ¤Þ¤¿¡¢²¾ÁÛ´Ø¿ô¤È¥Æ¥ó¥×¥ì¡¼¥È¤ò»È¤Ã¤¿¼ÂÁõ¤Ê¤Î¤Ç¡¢¥³¥ó¥Ñ¥¤¥ë¸å¤Î¥µ¥¤¥º¤ÏÂ礤¯¤Ê¤ê¤Þ¤¹¡£
+ ÊØÍø¤À¤±¤ÉÍê¤ê¤¹¤®¤º¡¢Â¾¤Î¾å¼ê¤¤¼ÂÁõ¤¬¤¢¤ì¤Ð¤½¤Á¤é¤òÍ¥À褷¤Æ¤ä¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+*/
+
+#include <cassert>
+#include <memory>
+#include <algorithm>
+
+#include <boost/intrusive_ptr.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include "shared_ptr.hpp"
+#include "pointer_facade.hpp"
+#include "reference_counter.hpp"
+
+namespace gintenlib
+{
+ // Àè¹ÔÀë¸À
+ template< typename T > struct clonable_ptr;
+
+ // ºÙ¡¹¤È¤·¤¿¼ÂÁõÍѤÎ̾Á°¶õ´Ö
+ namespace detail_
+ {
+ struct clonable_holder
+ {
+ clonable_holder() : p() {}
+
+ // Îã³° bad_alloc ¤òÅꤲ¤ë²ÄǽÀ¤¬¤¢¤ë
+ // ¤½¤Î¾ì¹ç ptr ¤Ïºï½ü¤µ¤ì¤ë
+ template<typename T>
+ explicit clonable_holder( T* ptr )
+ : p( holder<typename boost::remove_const<T>::type>::new_(ptr) )
+ {
+ }
+
+ template<typename T>
+ clonable_ptr<T> make_clone() const
+ {
+ clonable_holder temp( p->clone() );
+ return clonable_ptr<T>( temp.get<T>(), temp );
+ }
+ int use_count() const { return p->use_count(); }
+
+ private:
+ // ¥Ý¥¤¥ó¥¿ÊÝ»ýµ¡¹½
+ struct holder_base
+ : reference_counter<holder_base>
+ {
+ // ÇÉÀ¸Àè¤Î¥Ç¥¹¥È¥é¥¯¥¿¤Ë p ¤òºï½ü¤·¤Æ¤â¤é¤¦
+ virtual ~holder_base() throw () {}
+ // ¼«¿È¤òÊ£À½¤¹¤ë
+ virtual boost::intrusive_ptr<holder_base> clone() const = 0;
+
+ // ¥Ý¥¤¥ó¥¿¤òÆÀ¤ë
+ void* get(){ return p; }
+
+ protected:
+ holder_base( void* p_ )
+ : p( p_ ) {}
+
+ void* p;
+
+ }; // struct holder_base
+
+ template<typename T>
+ struct holder
+ : holder_base
+ {
+ explicit holder( T* src ) : holder_base( src ) {}
+ virtual ~holder() throw () { boost::checked_delete( static_cast<T*>(p) ); }
+
+ // ¿·¤·¤¯³ÎÊݤµ¤ì¤¿¥Ý¥¤¥ó¥¿ src ¤«¤é holder ¤òºî¤ë
+ // ºî¤ë²áÄø¤ÇÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ë¤Ï src ¤ò delete ¤¹¤ë
+ static boost::intrusive_ptr<holder> new_( T* src )
+ {
+ // Îã³°¤òÅꤲ¤ë²ÄǽÀ¤¬¤¢¤ë½èÍý¤ÎÁ°¤Ë¡¢¥Ý¥¤¥ó¥¿¤ò auto_ptr ¤ËÈóÆñ¤¹¤ë
+ std::auto_ptr<T> temp( src );
+
+ // ¤³¤³¤Î new ¤ÇÎã³°¤¬Åꤲ¤é¤ì¤ë²ÄǽÀ¤¬¤¢¤ë
+ holder* new_holder = new holder( src );
+ // ¤³¤³¤Ç src ¤Î´ÉÍý¤Ï holder ¤Ë°Ñ¾ù¤µ¤ì¤¿
+ temp.release();
+
+ // ¤ó¤Ç¤³¤³¤Ç¡¢ intrusive_ptr ¤Ë new_holder ¤Î´ÉÍý¤ò°Ñ¾ù¤¹¤ë
+ return boost::intrusive_ptr<holder>( new_holder );
+ }
+
+ // holder ¼«¿È¤È¡¢ÊÝ»ý¤µ¤ì¤Æ¤¤¤ë¥Ý¥¤¥ó¥¿¡¢Î¾Êý¤Î¥³¥Ô¡¼¤òºî¤ë
+ virtual boost::intrusive_ptr<holder_base> clone() const
+ {
+ return new_( new T( *static_cast<T*>(p) ) );
+ }
+
+ }; // struct holder
+
+ // ¼ÂÁõ¤Î¥Ý¥¤¥ó¥¿
+ boost::intrusive_ptr<holder_base> p;
+
+ // ¼ÂÁõÍѤÎ΢¸ý¥³¥ó¥¹¥È¥é¥¯¥¿
+ explicit clonable_holder
+ ( const boost::intrusive_ptr<holder_base>& ptr )
+ : p( ptr ) {}
+
+ // ¼ÂÁõÍѤΥݥ¤¥ó¥¿¼èÆÀ
+ template<typename T>
+ T* get() const
+ {
+ return static_cast<T*>( p->get() );
+ }
+
+ };
+
+ // pointer_facade ÍÑ¥«¥Æ¥´¥ê¥¿¥°
+ struct clonable_ptr_tag {} ;
+
+ } // namespace detail_
+
+ // ËÜÂÎ
+ template< typename T >
+ struct clonable_ptr
+ : pointer_facade< clonable_ptr<T>, T, detail_::clonable_ptr_tag >
+ {
+ template<typename U>
+ friend class clonable_ptr;
+
+ friend class detail_::clonable_holder;
+
+ // T ¤Î const À¤ò¤Ï¤º¤·¤¿·¿
+ typedef typename boost::remove_const<T>::type object_type;
+
+ // ¥Ç¥Õ¥©¥ë¥È¥³¥ó¥¹¥È¥é¥¯¥¿
+ clonable_ptr() : p(0), holder() {}
+
+ // ¥Ý¥¤¥ó¥¿¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
+ // Îã³°°ÂÁ´À¤¬ÌÌÅݤÀ¤¬
+ template<typename U>
+ explicit clonable_ptr( U* ptr )
+ : p( ptr ), holder( ptr ) {}
+
+ // ¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿
+ clonable_ptr( const clonable_ptr& src )
+ : p( src.p ), holder( src.holder ) {}
+ template< typename U >
+ clonable_ptr( const clonable_ptr<U>& src )
+ : p( src.p ), holder( src.holder ) {}
+
+ // ¥Ç¥¹¥È¥é¥¯¥¿
+ // ¥á¥ó¥Ð¤¬Å¬Àڤ˽èÍý¤·¤Æ¤¯¤ì¤ë¤¿¤á¡¢ÄêµÁ¤¹¤ëɬÍפʤ·
+ // ~clonable_ptr() {}
+
+ // nothrow swap ( for operator= )
+ void swap( clonable_ptr& other )
+ {
+ using std::swap;
+ swap( p, other.p );
+ swap( holder, other.holder );
+ }
+ friend void swap( clonable_ptr& one, clonable_ptr& another )
+ {
+ one.swap( another );
+ }
+
+ // ÂåÆþ½èÍý
+ clonable_ptr& operator=( const clonable_ptr& src )
+ {
+ clonable_ptr(src).swap( *this );
+ return *this;
+ }
+ template< typename U >
+ clonable_ptr& operator=( const clonable_ptr<U>& src )
+ {
+ clonable_ptr(src).swap( *this );
+ return *this;
+ }
+
+ // get pointer
+ // ¤³¤ì¤µ¤¨ÄêµÁ¤¹¤ì¤Ð¸å¤Ï pointer_facade ¤Ë¤è¤ê¼«Æ°ÄêµÁ¤µ¤ì¤ë
+ T* get() const { return p; }
+
+ void reset()
+ {
+ clonable_ptr().swap( *this );
+ }
+ template<typename U>
+ void reset( U* ptr )
+ {
+ clonable_ptr(ptr).swap( *this );
+ }
+
+ // ¾ðÊó¼èÆÀ
+ int use_count() const
+ {
+ return p ? holder.use_count() : 0;
+ }
+ bool unique() const
+ {
+ return use_count() == 1;
+ }
+ // °ìÈÖÂç»ö¤ÊÉôʬ
+ // ¼«¿È¤òÊ£À½¤¹¤ë
+ clonable_ptr<object_type> clone() const
+ {
+ // NULL ¤Ê¤é¤Ê¤Ë¤â¤·¤Ê¤¤
+ if( !p ){ return clonable_ptr<object_type>(); }
+
+ // holder ¤ËÍê¤ë
+ return holder.make_clone<object_type>();
+ }
+ // ¼«¿È¤¬Â¾¤Î¥Ý¥¤¥ó¥¿¤È»²¾ÈÀè¤ò¶¦Í¤·¤Æ¤¤¤ë¤È¤¡¢
+ // ¼«¿È¤òÊ£À½¤¹¤ë¤³¤È¤Ç¡¢»²¾ÈÀ褬ͣ°ì¤Î¸ºß¤È¤Ê¤ë¤è¤¦¤Ë¤¹¤ë
+ void to_unique()
+ {
+ // NULL ¤Ê¤é¤Ê¤Ë¤â¤·¤Ê¤¤
+ if( !p ){ return; }
+
+ // ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
+ if( !unique() )
+ {
+ clonable_ptr( this->clone() ).swap( *this );
+ }
+ }
+
+ // to_shared ´Ø¿ô´ØÏ¢
+
+ // Êä½õ¥Õ¥¡¥ó¥¯¥¿
+ struct deleter_for_to_shared
+ {
+ explicit deleter_for_to_shared( const clonable_ptr& src )
+ : p(src) {}
+ clonable_ptr p;
+
+ // operator() ¤Ï²¿¤â¤·¤Ê¤¤
+ void operator()( T* p_ )
+ {
+ // ¤¤¤ä¡¢assert ¤À¤±¤«¤±¤ë
+ using namespace std;
+ assert( p.get() == p_ );
+ }
+
+ }; // struct deleter_for_to_shared
+
+ // shared_ptr ¤Ø¤ÎÊÑ´¹
+ shared_ptr<T> to_shared() const
+ {
+ if( p )
+ {
+ return shared_ptr<T>( p, deleter_for_to_shared(*this) );
+ }
+ else
+ {
+ return shared_ptr<T>();
+ }
+ }
+ // friend ´Ø¿ôÈÇ
+ friend boost::shared_ptr<T> to_shared( const clonable_ptr& target )
+ {
+ return target.to_shared();
+ }
+
+ // pointer casts
+ template<typename Target, typename Source>
+ friend clonable_ptr<Target> static_pointer_cast( const clonable_ptr<Source>& );
+ template<typename Target, typename Source>
+ friend clonable_ptr<Target> dynamic_pointer_cast( const clonable_ptr<Source>& );
+ template<typename Target, typename Source>
+ friend clonable_ptr<Target> const_pointer_cast( const clonable_ptr<Source>& );
+
+ private:
+ typedef detail_::clonable_holder holder_type;
+
+ T* p;
+ holder_type holder;
+
+ // make_clone ¤«¤é¸Æ¤Ó½Ð¤¹¤¿¤á¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
+ clonable_ptr( T* ptr, const holder_type& h )
+ : p(ptr), holder(h) {}
+
+ }; // class clonable_ptr<T>
+
+ // pointer casts
+ template<typename Target, typename Source>
+ inline clonable_ptr<Target> static_pointer_cast( const clonable_ptr<Source>& t )
+ {
+ // ¤ß¤¿¤Þ¤ó¤Þ¡£¥Û¥ë¥À¡¼¤Ï¶¦ÍѤ¹¤ë
+ return clonable_ptr<Target>( static_cast<Target*>( t.p ), t.holder );
+ }
+ template<typename Target, typename Source>
+ inline clonable_ptr<Target> dynamic_pointer_cast( const clonable_ptr<Source>& t )
+ {
+ // dynamic_cast ¤Î¾ì¹ç¡¢¥¥ã¥¹¥È¤·¤¿·ë²Ì NULL ¤Ë¤Ê¤ë¤³¤È¤¬¤¢¤ë
+ Target* ptr = dynamic_cast<Target*>( t.p );
+ return ptr ? clonable_ptr<Target>( ptr, t.holder ) : clonable_ptr<Target>();
+ }
+ template<typename Target, typename Source>
+ inline clonable_ptr<Target> const_pointer_cast( const clonable_ptr<Source>& t )
+ {
+ return clonable_ptr<Target>( const_cast<Target*>( t.p ), t.holder );
+ }
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_CLONABLE_PTR_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_CONTEXT_ERROR_HPP_
+#define GINTENLIB_INCLUDED_CONTEXT_ERROR_HPP_
+
+/*
+ <gintenlib/context_error.hpp>
+
+ context_error: ʸ̮¥¨¥é¡¼¥¯¥é¥¹
+
+ ÀâÌÀ¡§
+ ´Ø¿ô¤Ê¤É¤ò¡¢¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¾õ¶·¤Ç¸Æ¤Ó½Ð¤·¤¿¤È¤¤ËÁ÷½Ð¤µ¤ì¤ëÎã³°¤Ç¤¹¡£
+
+*/
+
+#include <stdexcept>
+
+namespace gintenlib
+{
+ struct context_error
+ : std::logic_error
+ {
+ explicit context_error( const std::string& what_ )
+ : std::logic_error( what_ ) {}
+
+ }; // struct context_error
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_CONTEXT_ERROR_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_D_ENABLE_IF_HPP_
+#define GINTENLIB_INCLUDED_D_ENABLE_IF_HPP_
+
+/*
+
+ <gintenlib/d_enable_if.hpp>
+
+ d_enable_if ¡§ °ú¿ôÍÑ¤Ë boost::enable_if ¤Î»È¤¤¾¡¼ê¤ò¾¯¤·¤À¤±²þÁ±
+
+ Àë¸À¡§
+ struct dummy_arg_t {};
+
+ template<typename Cond>
+ struct d_enable_if : enable_if<Cond, dummy_arg_t> {};
+ template<typename Cond>
+ struct d_disable_if : disable_if<Cond, dummy_arg_t> {};
+
+ »ÈÍÑÎ㡧
+ // gintenlib::cast ¤Î¼ÂÁõ¤¬¤¤¤¤»ÈÍÑÎã¤Ê¤Î¤Ç¤½¤ì¤Ç¡ÊÃí¡§ÀΤμÂÁõ¡¢º£¤Ï enable_if ¤Ï»È¤Ã¤Æ¤Þ¤»¤ó¡Ë
+ using namespace gintenlib; // gintenlib::d_enable_if ¤È¤«½ñ¤¯¤ÎÀµÄ¾¤á¤ó¤É¤¤
+
+ // °ú¿ô¤ò Target ·¿¤Ø°ÅÌÛÊÑ´¹¤¹¤ë
+ // Ä̾ïÈÇ¡¢Target ¤¬»²¾È·¿¤Ç¤Ê¤±¤ì¤Ð¤³¤Ã¤Á¤¬¸Æ¤Ð¤ì¤ë
+ template< typename Target, typename Source >
+ inline Target cast( const Source& src,
+ typename d_disable_if< boost::is_reference<Target> >::type = dummy_arg_t() )
+ {
+ return src;
+ }
+
+ // »²¾ÈÈÇ
+ template< typename Target, typename Source >
+ inline Target cast( Source& src,
+ typename d_enable_if< boost::is_reference<Target> >::type = dummy_arg_t() )
+ {
+ return src;
+ }
+
+ // ¤Ê¤¼¤³¤¦½ñ¤¯¤«¡¢¤Á¤ç¤Ã¤È¤À¤±Êä¡£
+ // ¸«¤¿¤È¤ª¤êÂèÆó°ú¿ô¤Ï¥À¥ß¡¼¤Ç¡¢¤³¤¦½ñ¤«¤Ê¤¯¤Æ¤â¾ïÅå¼êÃʤȤ·¤Æ
+ // typename boost::disable_if< boost::is_reference<Target> >::type* = 0
+ // ¤Èµ½Ò¤¹¤ë¤³¤È¤â½ÐÍè¤ë¤Î¤À¤¬¡¢¤³¤Î¾ì¹ç¡¢¤¦¤Ã¤«¤ê
+ // cast<¤Ê¤ó¤¿¤é>( x, 0 );
+ // ¤È¤«¸Æ¤Ó½Ð¤·¤¿¾ì¹ç¤Ë¤â¡Ê¥¨¥é¡¼¤Ë¤Ê¤ë¤Ù¤¤Ï¤º¤¬¡Ë¥³¥ó¥Ñ¥¤¥ë¤¬Ä̤äƤ·¤Þ¤¦¡£
+ // ¥³¥ó¥Ñ¥¤¥ëÄ̤ë¤À¤±¤Ê¤é¤Þ¤À¤·¤â¡¢¤â¤· cast ¤¬£²°ú¿ô¥Ð¡¼¥¸¥ç¥ó¤Ç¿½ÅÄêµÁ¤µ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢
+ // ¡Ê¤¿¤È¤¨¤Ð cast<Src>( Target x, int param ) ¤È¤«¡Ë
+ // cast<Src>( x, 1 ) ¤Ê¤é¥³¥ó¥Ñ¥¤¥ëÄ̤뤱¤É cast<Src>( x, 0 ) ¤À¤ÈÄ̤é¤Ê¤¤¤è¡¢
+ // ¤È¤«¤¤¤¦°ÕÌ£ÉÔÌÀ¤Ê»öÂ֤ˤʤäƺ®Í𤹤붲¤ì¤¬¤¢¤ë¡£
+ // d_disable_if ¤¬¤¢¤ë¤Î¤Ï¤½¤Î¤¿¤á¡¢ÀìÍѤΥ¯¥é¥¹¤òÍÑ°Õ¤·¤Æ¤ë¤Î¤Ç
+ // ¤¦¤Ã¤«¤ê cast<Target>( x, 0 ) ¤È¤«¸Æ¤ó¤Ç¤â¥¨¥é¡¼¤Ë¤Ê¤ë¤Î¤Ç°Â¿´
+
+ µ¡Ç½¡§
+ ¾åµ¤Ç½ñ¤¤¤¿¤è¤¦¤Ë¡¢´Ø¿ô¤ËÂФ· enable_if ¤ò»È¤¦¾ì¹ç¤Ë¡¢
+ ¥À¥ß¡¼¤È¤Ê¤ë·¿¤¬Â¸ºß¤·¤Æ¤¤¤ë¤È³Ú¤Ê¤Î¤Ç¡¢ dummy_arg_t ¤òͽ¤áÍÑ°Õ¤·¤Æ¤ª¤¤Þ¤¹
+ ¤Þ¤¿¡¢¤½¤ÎÅÔÅÙ¥À¥ß¡¼·¿¤ò enable_if ¤ÎÂèÆó°ú¿ô¤Ç»ØÄꤹ¤ë¤Î¤ÏÌÌÅݤʤΤǡ¢¤½¤Î¼ê´Ö¤â¾Ê¤¤Þ¤¹¡£
+ ¤Á¤Ê¤ß¤Ë d_enable_if ¤Î d ¤Ï dummy ¤Îά¡£
+
+*/
+
+#include "enable_if.hpp"
+
+namespace gintenlib
+{
+ // enable_if ÍÑ¥À¥ß¡¼°ú¿ô¥¯¥é¥¹
+ struct dummy_arg_t {};
+
+ // ¥À¥ß¡¼°ú¿ôÈÇ enable_if
+ template<typename Cond>
+ struct d_enable_if : enable_if<Cond, dummy_arg_t> {};
+ template<typename Cond>
+ struct d_disable_if : disable_if<Cond, dummy_arg_t> {};
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_D_ENABLE_IF_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_DEEP_PTR_HPP_
+#define GINTENLIB_INCLUDED_DEEP_PTR_HPP_
+
+/*
+
+ <gintenlib/deep_ptr.hpp>
+
+ deep_ptr ¡§ ¿¼¤¤¥³¥Ô¡¼¤ò¤¹¤ë¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿
+
+ Àë¸À¡§
+ template<typename T>
+ struct deep_ptr;
+
+ // ´ðËÜŪ¤Ê¥á¥½¥Ã¥É¤Ï¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ÈƱ¤¸¤Ê¤Î¤Ç¾Êά
+
+ µ¡Ç½¡§
+ ¥³¥Ô¡¼¤¹¤ë¤È¤¤Ë¡¢¥ª¥Ö¥¸¥§¥¯¥È¤Î¡Ö¿¼¤¤¥³¥Ô¡¼¡×¤òÀ½ºî¤¹¤ë¥Ý¥¤¥ó¥¿¡£
+ ¤³¤Î¥¯¥é¥¹¤Ï´ðËÜŪ¤Ë boost::optional ¤ÇÂåÍѤǤ¤Þ¤¹¡£
+ ¤½¤Î¤¿¤á¡¢¤¢¤¨¤Æ deep_ptr ¤ò»È¤¦¥á¥ê¥Ã¥È¤Ï¿¤¯¤¢¤ê¤Þ¤»¤ó¡£
+
+ ¡¦new ¤µ¤ì¤¿¤â¤Î¤òľÀܼõ¤±¼è¤ê¤¿¤¤¾ì¹ç
+ ¡¦ÊÑ¿ô¼«ÂΤΥµ¥¤¥º¤¬µ¤¤Ë¤Ê¤ë¾ì¹ç
+ ¡¦Ì¤ÄêµÁ¤Î·¿¤ò»ý¤¿¤»¤¿¤¤¾ì¹ç¡Ê¥¯¥é¥¹ÆâÉô¤Ç¡¢¤½¤Î¥¯¥é¥¹¤ÎÃͤò»ý¤Á¤¿¤¤¾ì¹ç¤Ê¤É
+
+ ¤»¤¤¤¼¤¤¤¬¤³¤ÎÄøÅ٤Ǥ¹¡£¤½¤ÎÃæ¤ÇÈæ³ÓŪ½ÅÍפʤΤ¬»°ÈÖÌܤǤ¢¤ê¡¢
+ boost::optional ¤Î¾ì¹ç¡¢boost::optional<T> ·¿¤ÎÊÑ¿ô¤òÄêµÁ¤·¤¿»þÅÀ¤Ç T ¤Î·¿¤ÎÄêµÁ¤¬·è¤Þ¤Ã¤Æ¤¤¤Ê¤¤¤È¤¤¤±¤Þ¤»¤ó¡Ê sizeof(T) ¤¬É¬ÍפʤΤǡˡ£
+ ¤·¤«¤· deep_ptr ¤Ê¤é¡¢¼ÂºÝ¤Ë¥³¥Ô¡¼¤µ¤ì¤ë»þ¤Þ¤Ç¡¢Âоݤη¿¤ÎÄêµÁ¤ò¿¤Ð¤»¤Þ¤¹¡Ê sizeof(T*) ¤Ï¾ï¤Ë°ìÄê¤Ê¤Î¤Ç¡Ë¡£
+ ¤È¤¤¤¦¤ï¤±¤Ç¡¢new ¤Î¥³¥¹¥È¤¬·Ú¤¤¥ª¥Ö¥¸¥§¥¯¥È¡Ê¥á¥â¥ê¥×¡¼¥ë¤ò»È¤Ã¤¿ operator new ¤¬¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤È¤«¡Ë¤Ê¤é¤Ð°Õ³°¤È»È¤¤Æ»¤Ï¤¢¤ë¤Î¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ ¤Á¤Ê¤ß¤Ë¤³¤Î¥Ý¥¤¥ó¥¿¤Ï¡¢¥Ð¥°ËɻߤΤ¿¤áƱ¤¸·¿Æ±»Î¡Ê const Åù¤Î½¤¾þ»Ò¤Ï½ü¤¯¡Ë¤Ç¤·¤«¥³¥Ô¡¼¤Ç¤¤Þ¤»¤ó¡£
+
+*/
+
+#include <boost/scoped_ptr.hpp>
+
+#include "shared_ptr.hpp"
+#include "pointer_facade.hpp"
+#include "is_same_class.hpp"
+
+namespace gintenlib
+{
+ namespace detail_{ struct deep_ptr_tag_{}; }
+
+ template< typename T >
+ struct deep_ptr
+ : pointer_facade< deep_ptr<T>, T, detail_::deep_ptr_tag_ >
+ {
+ template<typename U>
+ friend class deep_ptr;
+
+ typedef typename boost::remove_cv<T>::type object_type;
+
+ // ¥Ç¥Õ¥©¥ë¥È¥³¥ó¥¹¥È¥é¥¯¥¿
+ deep_ptr() : p() {}
+
+ // ¥Ý¥¤¥ó¥¿¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
+ template<typename U>
+ explicit deep_ptr( U* p_,
+ typename enable_if_same_class<T, U>::type* = 0 )
+ : p( p_ ) {}
+
+ // ¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿
+ deep_ptr( const deep_ptr& src )
+ : p( src.make_clone_() ) {}
+
+ // ¾¤Î¼ïÎà¤Î deep_ptr ¤«¤é¤ÎÊÑ´¹¤Ï¡¢const ¤ä volatile ½¤¾þ¤·¤«°Û¤Ê¤é¤Ê¤¤¾ì¹ç¤Î¤ßOK
+ template< typename U >
+ deep_ptr( const deep_ptr<U>& src,
+ typename enable_if_same_class<T, U>::type* = 0 )
+ : p( src.make_clone_() ) {}
+
+ // ¥Ç¥¹¥È¥é¥¯¥¿
+ // scoped_ptr() ¤Î¤ª¤«¤²¤Ç²¿¤â¤·¤Ê¤¯¤Æ¤¤¤¤
+ // ~deep_ptr(){}
+
+ // nothrow swap ( for operator= )
+ void swap( deep_ptr& other )
+ {
+ p.swap( other.p );
+ }
+ friend void swap( deep_ptr& one, deep_ptr& another )
+ {
+ one.swap( another );
+ }
+
+ // ÂåÆþ±é»»¤Ï copy ¤·¤Æ swap
+ deep_ptr& operator=( const deep_ptr& src )
+ {
+ deep_ptr( src ).swap( *this );
+ return *this;
+ }
+ template< typename U >
+ deep_ptr& operator=( const deep_ptr<U>& src )
+ {
+ deep_ptr( src ).swap( *this );
+ return *this;
+ }
+
+ // get pointer
+ // ¤³¤ì¤È pointer_facade ¤«¤é¤¤¤í¤¤¤í¤È¼«Æ°À¸À®
+ T* get() const { return p.get(); }
+
+ // Ãæ¿È¤òÀÚ¤êÂؤ¨¤ë
+ void reset()
+ {
+ deep_ptr().swap( *this );
+ }
+ template<typename U>
+ void reset( U* ptr )
+ {
+ deep_ptr( ptr ).swap( *this );
+ }
+
+ // shared_ptr ¤ËÊÑ´¹¤¹¤ë
+ shared_ptr<T> to_shared() const
+ {
+ return shared_ptr<T>( make_clone_() );
+ }
+ // friend ÈÇ
+ friend shared_ptr<T> to_shared( const deep_ptr& target )
+ {
+ return target.to_shared();
+ }
+
+ private:
+ boost::scoped_ptr<T> p;
+
+ // p ¤ËÊÝ»ý¤µ¤ì¤Æ¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ÎÊ£À½¤òºî¤ë
+ object_type* make_clone_() const
+ {
+ return p ? new object_type(*p) : 0;
+ }
+
+ }; // class deep_ptr<T>
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_DEEP_PTR_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_DELETER_HPP_
+#define GINTENLIB_INCLUDED_DELETER_HPP_
+
+/*
+
+ <gintenlib/deleter.hpp>
+
+ deleter ¡§ ñ½ã¤Ê delete ±é»»»Ò¤ÈÅù²Á¤Ê¥Õ¥¡¥ó¥¯¥¿
+ typed_deleter ¡§ ·¿¤Î»ØÄꤵ¤ì¤¿ deleter
+ dummy_deleter ¡§ ²¿¤â¤·¤Ê¤¤¥Õ¥¡¥ó¥¯¥¿
+ typed_dummy_deleter ¡§ ·¿¤¬»ØÄꤵ¤ì¤Æ¤ë¤±¤É²¿¤â¤·¤Ê¤¤¥Õ¥¡¥ó¥¯¥¿
+
+ µ¡Ç½¡§
+ ¥Ý¥¤¥ó¥¿ delete ÍѤδؿô¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡£¤½¤ì°Ê³°¤Î²¿Êª¤Ç¤â¤¢¤ê¤Þ¤»¤ó¡£
+ deleter ¤Ï boost::checked_delete ¤ò¸Æ¤ó¤Ç¤Þ¤¹¤¬¡¢¤³¤ÎÃæ¤Ç¤Ïñ¤Ë delete ±é»»»Ò¤ò¸Æ¤ó¤Ç¤¤¤ë¤À¤±¡£
+ dummy_deleter ¤Ï delete ±é»»»Ò¤¹¤é¸Æ¤Ð¤Ê¤¤¡¢Ã±¤Ê¤ë¥×¥ì¡¼¥¹¥Û¥ë¥À¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£
+ ¤½¤ì¤¾¤ì·¿ÉեС¼¥¸¥ç¥ó¤â¤¢¤ê¡¢¤½¤ì¤é¤Ï unary_function ¤Î¾ò·ï¤òËþ¤¿¤·¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include <functional>
+#include <boost/checked_delete.hpp>
+
+namespace gintenlib
+{
+ // ¤¿¤Àñ¤Ë delete ¤¹¤ë¤À¤±¤Î¥Õ¥¡¥ó¥¯¥¿
+ struct deleter
+ {
+ typedef void result_type;
+
+ template<typename T>
+ result_type operator()( T* p ) const throw()
+ {
+ boost::checked_delete( p );
+ }
+
+ }; // struct deleter
+
+ // ·¿¤Î«Çû¤µ¤ì¤¿ deleter
+ template<typename T>
+ struct typed_deleter : std::unary_function<T*, void>
+ {
+ void operator()( T* p ) const throw()
+ {
+ boost::checked_delete( p );
+ }
+
+ }; // struct typed_deleter<T>
+
+ // ²¿¤â¤·¤Ê¤¤ deleter
+ struct dummy_deleter
+ {
+ typedef void result_type;
+
+ template<typename T>
+ result_type operator()( T* p ) const throw() {}
+
+ }; // struct dummy_deleter
+
+ // ·¿Â«Çû¤µ¤ì¤Æ¤ë¤±¤É²¿¤â¤·¤Ê¤¤ deleter
+ template<typename T>
+ struct typed_dummy_deleter : std::unary_function<T*, void>
+ {
+ void operator()( T* p ) const throw() {}
+
+ }; // struct typed_dummy_deleter<T>
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_DELETER_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_ENABLE_IF_HPP_
+#define GINTENLIB_INCLUDED_ENABLE_IF_HPP_
+
+/*
+
+ <gintenlib/enable_if.hpp>
+
+ enable_if ¡§ boost::enable_if ¤Î using Àë¸À
+
+ Àë¸À¡§
+ using boost::enable_if;
+ using boost::enable_if_c;
+ using boost::disable_if;
+ using boost::disable_if_c;
+
+ µ¡Ç½¡§
+ ñ½ã¤Ë gintenlib Æâ¤Ç boost::enable_if ¤ò»È¤¦µ¡²ñ¤Ï¿¤¤¤Î¤Ç¡¢
+ ͽ¤á using Àë¸À¤·¤Æ¤ª¤±¤Ð¡¢¤¤¤Á¤¤¤Á boost:: ¤È»ØÄꤷ¤Æ¤ä¤ëɬÍפ¬Ìµ¤¯¤Æ³Ú¡¢¤À¤±¤Î¥Ø¥Ã¥À¤Ç¤¹¡£
+ ¤¢¤È¤Ï TR1 ¤Ø¤ÎÂбþ¤ò¤·¤ä¤¹¤¤¤è¤¦¤Ë¡¢¤È¤¤¤¦°ÕµÁ¤â¤¢¤ê¤Þ¤¹¡£
+ ¤½¤Î¾ì¹ç¤Ï¸ß´¹À¤¬¼º¤ï¤ì¤ë²ÄǽÀ¤â¤¢¤ë¤Î¤Ç¡¢¤ä¤ë¤È¤¹¤ì¤Ð¥á¥¸¥ã¡¼¥Ð¡¼¥¸¥ç¥ó¥¢¥Ã¥×»þ¤Ç¤·¤ç¤¦¤¬¡£
+
+*/
+
+#include <boost/utility/enable_if.hpp>
+
+namespace gintenlib
+{
+ using boost::enable_if;
+ using boost::enable_if_c;
+ using boost::disable_if;
+ using boost::disable_if_c;
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_ENABLE_IF_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_FACTORIZE_HPP_
+#define GINTENLIB_INCLUDED_FACTORIZE_HPP_
+
+/*
+ <gintenlib/factorize.hpp>
+
+ factorize ¡§ À°¿ô¤Î°ø¿ôʬ²ò
+
+ Àë¸À¡§
+ template<typename Int, typename OutIte>
+ OutIte factorize( Int n, OutIte out );
+
+ µ¡Ç½¡§
+ À°¿ô n ¤ÎÁÇ°ø¿ô¤ò¡¢¾®¤µ¤¤½ç¤Ë½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿ out ¤Ë½ÐÎϤ·¤Þ¤¹¡£
+ n ¤Ï 0 ¤è¤êÂ礤¯¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡Ê 0 °Ê²¼¤Ë¤Ê¤é¤Ê¤¤¤è¤¦»öÁ°¤Ë¥Á¥§¥Ã¥¯¤¹¤Ù¤¤Ç¤¹¡Ë¡£
+ ¡ÖÀ°¿ô¡×¤È¤·¤Æ»È¤¨¤ë·¿¤Ï¡¢À°¿ô·¿¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¡¢»Í§±é»»¤ª¤è¤ÓÂç¾®Èæ³Ó¤¬²Äǽ¤Ê·¿¤Ç¤¹¡£
+
+ »ÈÍÑÎ㡧
+ // 143 = 11 * 13
+ // '11 13 '¤Èɽ¼¨¤µ¤ì¤ë
+ gintenlib::factorize( 143, std::ostream_iterator<int>( std::cout, " " ) );
+
+ Ê䡧
+ ¡¦Ã±½ã¤Ê¥Æ¥ó¥×¥ì¡¼¥È¤Ê¤Î¤Ç¡¢·¿¤ò»ØÄꤷ¤¿¤¤¾ì¹ç¤Ï factorize<short>( 143, out ) ¤Î¤è¤¦¤Ë½ñ¤±¤Þ¤¹¡£
+ ¡¡¤¬¡¢Â¾¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤Ï¾å¼ê¤¯¤¤¤«¤Ê¤¤¤³¤È¤â¤¢¤ë¤¿¤á¡¢Åý°ìÀ¤Î°Ù¤Ë¤â gintenlib::cast ¤òÍѤ¤¤¿Êý¤¬¤è¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ ¡¡¤½¤Î¾ì¹ç¤Ï factorize( cast<short>(143), out ) ¤Î¤è¤¦¤Ë½ñ¤¤Þ¤¹¡Ê gintenlib:: ¤Ïά¡Ë
+
+*/
+
+#include <cassert>
+#include <stdexcept>
+
+namespace gintenlib
+{
+ // ÁÇ°ø¿ôʬ²ò¤·¤Æ out ¤Ë½ÐÎÏ
+ template<typename Int, typename OutIte>
+ OutIte factorize( Int n, OutIte out )
+ {
+ // °ú¿ô¥Á¥§¥Ã¥¯
+ if( n <= 0 )
+ {
+ throw std::invalid_argument( "gintenlib.factorize: n should be greater than 0" );
+ }
+
+ // Êä½õ¥Õ¥¡¥ó¥¯¥¿
+ // Ʊ¤¸µ½Ò¤ò²¿²ó¤â½ñ¤¯¤Î¤ÏÌÌÅݤʤΤÇ
+ struct helper_
+ {
+ Int& n; OutIte& out;
+ helper_( Int& n_, OutIte& out_ )
+ : n(n_), out(out_) {}
+
+ bool operator()( Int i ) const
+ {
+ using namespace std;
+ assert( i > 1 && n > 0 );
+
+ while( n % i == 0 )
+ {
+ n /= i;
+ *out = i;
+ ++out;
+ }
+
+ if( i * i > n )
+ {
+ if( n > 1 )
+ {
+ *out = n;
+ ++out;
+ n = 1;
+ }
+ return false;
+ }
+
+ return true;
+ }
+ } doit( n, out );
+
+ // ¼ÂºÝ¤Î½èÍý
+ // ¤Þ¤º 2 ¤È 3¡¢¤³¤ì¤Ï i ¤â´Þ¤á¤Æ¥¤¥ó¥é¥¤¥óŸ³«¤µ¤ì¤ë¤È¤¤¤¤¤Ê
+ if( !doit(2) ){ return out; }
+ if( !doit(3) ){ return out; }
+
+ // ¼¡¤ÏÈÆÍѤÀ¤¬¡¢2 ¤È 3 ¤ÎÇÜ¿ô¤ÏÁÇ¿ô¤Ç¤Ï¤Ê¤¤¤Î¤Ç¾Êά¤¹¤ë
+ // ¤½¤Î¤¿¤á¤Ë¤Ï¡¢6n - 1 ¤È 6n + 1 ¤Î¤ß¸¡º÷¤¹¤ì¤Ð¤è¤¤
+ Int i = 5;
+ for(;;)
+ {
+ // 6n - 1
+ if( !doit(i) ){ return out; }
+ i += 2;
+
+ // 6n + 1
+ if( !doit(i) ){ return out; }
+ i += 4;
+ }
+ }
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_FACTORIZE_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_IGNORE_HPP_
+#define GINTENLIB_INCLUDED_IGNORE_HPP_
+
+/*
+
+ <gintenlib/ignore.hpp>
+
+ ignore ¡§ ¤¢¤é¤æ¤ëÂåÆþ¤ò̵»ë¤¹¤ëÊÑ¿ô
+
+ Àë¸À¡§
+ using boost::fusion::ignore;
+
+ µ¡Ç½¡§
+ ¤¢¤é¤æ¤ëÂåÆþÁàºî¤ò¼õ¤±ÉÕ¤±¤Ê¤¤ÊÑ¿ô ignore ¤òÄêµÁ¤·¤Þ¤¹¡£
+
+ »ÈÍÑÎ㡧
+ struct vector
+ {
+ double x, y;
+
+ vector( double x_, double y_ ) : x(x_), y(y_) {}
+
+ template<typename X, typename Y>
+ void get_xy( X& x_, Y& y_ ){ x_ = x; y_ = y; }
+
+ };
+
+ vector v( 1, 2 );
+ double x;
+ v.get_xy( x, gintenlib::ignore );
+
+ Ê䡧
+ ¡¦¤¢¤ó¤Þ¤ê»È¤ï¤Ê¤¤¤«¤â
+
+*/
+
+#include <boost/fusion/container/generation/ignore.hpp>
+
+namespace gintenlib
+{
+ using boost::fusion::ignore;
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_IGNORE_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_INTRUSIVE_TO_SHARED_HPP_
+#define GINTENLIB_INCLUDED_INTRUSIVE_TO_SHARED_HPP_
+
+/*
+
+ <gintenlib/intrusive_to_shared.hpp>
+
+ intrusive_to_shared ¡§ intrusive_ptr ¤ò shared_ptr ¤ËÊÑ´¹
+
+ Àë¸À¡§
+ template<typename T>
+ boost::shared_ptr<T> intrusive_to_shared( const boost::intrusive_ptr<T>& p );
+
+ template<typename T>
+ boost::shared_ptr<T> intrusive_to_shared( T* p, bool add_ref = true );
+
+ template<typename T>
+ boost::shared_ptr<T> to_shared( const boost::intrusive_ptr<T>& p );
+
+ µ¡Ç½¡§
+ intrusive_ptr ¤ò shared_ptr ¤ËÊÑ´¹¤·¤Þ¤¹¡£
+ intrusive_ptr_add_ref ¤ä intrusive_ptr_release ¤Î¥³¥¹¥È¤¬¹â¤¤¾ì¹ç¤ä¡¢
+ ¤¢¤ë¤¤¤Ïñ¤Ë shared_ptr ¤È¤·¤Æ¤ÎÃͤ¬Íߤ·¤¤¾ì¹ç¤Ê¤É¤Ë»È¤¨¤Þ¤¹¡£
+ ¤Ê¤ª¥Ø¥Ã¥À̾¤Ï intrusive_to_shared ¤Ç¤¹¤¬¡¢¾Êά̾¤Ç¤¢¤ë to_shared ¤Ç¤â»È¤¨¤Þ¤¹¡£
+ ¤à¤·¤í <gintenlib/to_shared.hpp> ¤È¤Î·ó¤Í¹ç¤¤¤«¤é¡¢¤³¤Á¤é¤ò»È¤¦¤³¤È¤ò¿ä¾©¤·¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include "shared_ptr.hpp"
+
+#include <cassert>
+#include <boost/intrusive_ptr.hpp>
+
+namespace gintenlib
+{
+ // deleter ¤È¤·¤Æ»È¤¦Êä½õ¥Õ¥¡¥ó¥¯¥¿
+ struct intrusive_ptr_releaser
+ {
+ typedef void result_type;
+
+ // ptr ¤ò¥ê¥ê¡¼¥¹¤¹¤ë
+ template<typename T>
+ void operator()( T* ptr ) const
+ {
+ using namespace std;
+ using namespace boost; // for intrusive_ptr_release
+
+ assert( ptr != 0 );
+ intrusive_ptr_release(ptr);
+ }
+
+ }; // class intrusive_ptr_releaser
+
+ // ËÜÂÎ
+ // intrusive_ptr ÈÇ
+ template<typename T>
+ inline shared_ptr<T> intrusive_to_shared( const boost::intrusive_ptr<T>& p )
+ {
+ // À¸¥Ý¥¤¥ó¥¿ÈǤËñ½ã¤ËžÁ÷¤¹¤ë¤À¤±
+ return intrusive_to_shared( p.get(), true );
+ }
+ // À¸¥Ý¥¤¥ó¥¿ÈÇ
+ template<typename T>
+ inline shared_ptr<T> intrusive_to_shared( T* p, bool add_ref = true )
+ {
+ using namespace boost; // for intrusive_ptr_add_ref
+
+ if(p)
+ {
+ // »²¾È¥«¥¦¥ó¥ÈÁý¤ä¤·¤Æ¤«¤é shared_ptr ¤ËÆͤùþ¤à
+ // boost::shared_ptr ¤Ï¥³¥ó¥¹¥È¥é¥¯¥¿¤ÇÎã³°¤òÅꤲ¤¦¤ë¤¬¡¢¤½¤Î¾ì¹ç¤Ç¤â
+ // ¤Á¤ã¤ó¤Èºï½ü¥Õ¥¡¥ó¥¯¥¿¤ò¸Æ¤Ó½Ð¤·¤Æ¤¯¤ì¤ë¤Î¤ÇÌäÂê¤Ê¤¤
+ if( add_ref ){ intrusive_ptr_add_ref( p ); }
+ return shared_ptr<T>( p, intrusive_ptr_releaser() );
+ }
+
+ // NULL ¤Î¾ì¹ç¤Ï¶õ¤Î shared_ptr ¤òÊÖ¤¹
+ return shared_ptr<T>();
+ }
+
+ // ¾Êά̾¾Î
+ // ¾¤Î¾ì½ê¤Ç to_shared ¤Î°ìÈÌŪ¤Ê¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ËÂФ¹¤ëÄêµÁ¤â¤¢¤ë¤¬¡¢
+ // intrusive_ptr ¤Ë´Ø¤·¤Æ¤Ï¤³¤Á¤é¤ÎÊý¤¬¸úΨ¤¬Îɤ¤¡£
+ template<typename T>
+ inline shared_ptr<T> to_shared( const boost::intrusive_ptr<T>& p )
+ {
+ // ñ½ã¤ËžÁ÷¤¹¤ë¤À¤±
+ return intrusive_to_shared( p );
+ }
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_INTRUSIVE_TO_SHARED_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_IS_SAME_CLASS_HPP_
+#define GINTENLIB_INCLUDED_IS_SAME_CLASS_HPP_
+
+/*
+ <gintenlib/is_same_class.hpp>
+
+ is_same_class ¡§ const, volatile ¤ò½ü¤¤¤¿¾õÂ֤Ǥη¿¤ÎÈæ³Ó
+
+ Àë¸À¡§
+ template< typename T1, typename T2 >
+ class is_same_class
+ {
+ static bool const value;
+ };
+ template< typename T1, typename T2, typename T = void >
+ class enable_if_same_class
+ : enable_if< is_same_class<T1, T2>, T > {};
+
+ µ¡Ç½¡§
+ ²¼¤ÎÄêµÁ¤ò¸«¤ì¤Ð°ìÌÜÎÆÁ³¡£remove_cv ¤·¤Æ is_same Èæ³Ó¤·¤Þ¤¹¡£
+ Èæ³ÓŪ¿¤¤Áàºî¤Ê¤Î¤Ç¡¢Ã»¤¯»È¤¨¤ë¤è¤¦¤Ë¡£
+
+*/
+
+#include "enable_if.hpp"
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace gintenlib
+{
+ // CV ½¤¾þ¤ò½ü¤¤¤ÆƱ¤¸¥¯¥é¥¹¤«Èݤ«
+ template<typename T1, typename T2>
+ struct is_same_class
+ : boost::is_same< typename boost::remove_cv<T1>::type,
+ typename boost::remove_cv<T2>::type > {};
+
+ // CV ½¤¾þ¤ò½ü¤¤¤ÆƱ¤¸¤Ê¤é͸ú¤Ë¤Ê¤ë
+ template<typename T1, typename T2, typename T = void>
+ struct enable_if_same_class
+ : enable_if< is_same_class<T1, T2>, T > {};
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_IS_SAME_CLASS_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_LEXICAL_CAST_DEFAULT_HPP_
+#define GINTENLIB_INCLUDED_LEXICAL_CAST_DEFAULT_HPP_
+
+/*
+ <gintenlib/lexical_cast_default.hpp>
+
+ lexical_cast_default ¡§ Îã³°¤òÅꤲ¤Ê¤¤ boost::lexical_cast
+
+ Àë¸À¡§
+ template< typename Target, typename Source >
+ Target lexical_cast_default( const Source& src );
+
+ template< typename Target, typename Source >
+ Target lexical_cast_default( const Source& src, const Target& default_value );
+
+ µ¡Ç½¡§
+ boost::lexical_cast ¤ÈƱÍͤˡ¢Ê¸»úÎóɽ¸½¤òÃçΩ¤Á¤Ë·¿ÊÑ´¹¤ò¹Ô¤¤¤Þ¤¹¡£
+ boost::lexical_cast ¤È¤Î°ã¤¤¤Ï¡¢¼ºÇÔ¤·¤¿¾ì¹ç¤ËÎã³°¤òÅꤲ¤º default_value ¤òÊÖ¤¹ÅÀ¡£
+ ÂèÆó°ú¿ô¤ò¾Êά¤·¤¿¾ì¹ç¤Ë¤Ï¡¢¥Ç¥Õ¥©¥ë¥È½é´ü²½Ãͤ¬ÊÖ¤ê¤Þ¤¹¡£
+
+ »ÈÍÑÎ㡧
+ // hoge ¤Ï¿ôÃͤòɽ¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Ê¤¤¡Öʸ»úÎó¤ËÊÑ´¹¤Ç¤¤ë²¿¤«¡×
+ int i = gintenlib::lexical_cast_default<int>( hoge, -1 ),
+ j = gintenlib::lexical_cast_default<int>( hoge );
+ // hoge ¤¬¿ôÃͤòɽ¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢i = -1, j = 0¡Êint¤Î½é´üÃ͡ˤˤʤë
+
+ Ê䡧
+ ¡¦´ðËÜŪ¤Ë boost::lexical_cast ¤ÎÎã³°½èÍý¤¬ÌÌÅݤʾì¹ç¤Ë»È¤¤¤Þ¤¹¡£
+ ¡¦default_value¤ÈƱ¤¸Ãͤ¬Ê֤俤Ȥ·¤Æ¤â¡¢¥¥ã¥¹¥È¤Ë¼ºÇÔ¤·¤¿¤È¤Ï¸Â¤é¤Ê¤¤¤Î¤ÇÍ×Ãí°Õ¡£
+ ¡ÊÊÑ´¹¸µ¤Îɽ¸½¤¹¤ëÃͤ¬¡¢¤¿¤Þ¤¿¤Þ default_value ¤ÈƱ¤¸¤À¤Ã¤¿¤Î¤«¤â¤·¤ì¤Ê¤¤¤Î¤Ç¡Ë
+
+*/
+
+#include <boost/lexical_cast.hpp>
+
+namespace gintenlib
+{
+ // src ¤òʸ»úÎó¤ËÊÑ´¹¤·¡¢¤½¤Îʸ»úÎó¤ò Target ·¿¤ËÊÑ´¹
+ // ¼ºÇÔ¤·¤¿¾ì¹ç¤Ë¤Ï default_value ¤¬ÊÖ¤ë
+ template< typename Target, typename Source >
+ Target lexical_cast_default( const Source& src, const Target& default_value )
+ {
+ using namespace boost;
+
+ try
+ {
+ return lexical_cast<Target>( src );
+ }
+ catch( bad_lexical_cast )
+ {
+ return default_value;
+ }
+
+ } // lexical_cast_default
+
+ // src ¤òʸ»úÎó¤ËÊÑ´¹¤·¡¢¤½¤Îʸ»úÎó¤ò Target ·¿¤ËÊÑ´¹
+ // ¼ºÇÔ¤·¤¿¾ì¹ç¤Ë¤Ï Target() ¤¬ÊÖ¤ë
+ template< typename Target, typename Source >
+ Target lexical_cast_default( const Source& src )
+ {
+ using namespace boost;
+
+ try
+ {
+ return lexical_cast<Target>( src );
+ }
+ catch( bad_lexical_cast )
+ {
+ return Target();
+ }
+
+ } // lexical_cast_default
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_LEXICAL_CAST_DEFAULT_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_LEXICAL_CONVERT_HPP_
+#define GINTENLIB_INCLUDED_LEXICAL_CONVERT_HPP_
+
+/*
+
+ <gintenlib/lexical_convert.hpp>
+
+ lexical_convert ¡§ C¥é¥¤¥¯¤Ë½èÍý¤Ç¤¤ë boost::lexical_cast
+
+ Àë¸À¡§
+ template< typename Target, typename Source >
+ bool lexical_convert( Target& dest, const Source& src );
+
+ µ¡Ç½¡§
+ ÂèÆó°ú¿ô¤ò boost::lexical_cast ¤Ë¤è¤Ã¤ÆÊÑ´¹¤·¡¢¤½¤Î·ë²Ì¤òÂè°ì°ú¿ô¤ËÂåÆþ¤·¤Þ¤¹¡£
+ Àµ¾ï¤ËÊÑ´¹¤¬¹Ô¤ï¤ì¤¿¾ì¹ç¡¢Ìá¤êÃͤȤ·¤Æ true ¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£
+ ÊÑ´¹¤¬¼ºÇÔ¤·¤¿¾ì¹ç¤Ë¤Ï¡¢Âè°ì°ú¿ô¤ÏÊѲ½¤»¤º¡¢Ìá¤êÃÍ¤Ï false ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ »ÈÍÑÎ㡧
+ // hoge ¤Ï¿ôÃͤòɽ¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Ê¤¤¡Öʸ»úÎó¤ËÊÑ´¹¤Ç¤¤ë²¿¤«¡×
+ int i;
+ if( gintenlib::lexical_convert( i, hoge ) )
+ {
+ // hoge ¤¬¿ôÃͤòɽ¤·¤Æ¤¤¤¿¾ì¹ç¤Î½èÍý
+ }
+ else
+ {
+ // hoge ¤¬¿ôÃͤòɽ¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¤Î½èÍý
+ }
+
+ Ê䡧
+ ¡¦´ðËÜŪ¤Ë boost::lexical_cast ¤ÎÎã³°½èÍý¤¬ÌÌÅݤʾì¹ç¤Ë»È¤¤¤Þ¤¹¡£
+ ¡¦»ÈÍÑÎã¤Î¥½¡¼¥¹¥³¡¼¥É¤Ï¡¢boost::lexical_cast ¤Î¤ß¤ò»È¤Ã¤Æ¼¡¤Î¤è¤¦¤Ë½ñ¤¯»ö¤â½ÐÍè¤Þ¤¹¡§
+ int i;
+ try
+ {
+ i = boost::lexical_cast<int>(hoge);
+
+ // hoge ¤¬¿ôÃͤòɽ¤·¤Æ¤¤¤¿¾ì¹ç¤Î½èÍý
+ }
+ catch( boost::bad_lexical_cast )
+ {
+ // hoge ¤¬¿ôÃͤòɽ¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¤Î½èÍý
+ }
+
+*/
+
+#include <boost/lexical_cast.hpp>
+
+namespace gintenlib
+{
+ // src ¤òʸ»úÎó¤ËÊÑ´¹¤·¡¢¤½¤Îʸ»úÎó¤ò Target ·¿¤ËÊÑ´¹¤·¤Æ dest ¤ËÂåÆþ
+ // À®¸ù¤·¤¿¾ì¹ç¤Ë¤Ï true ¤¬¡¢¼ºÇÔ¤·¤¿¾ì¹ç¤Ë¤Ï false ¤¬ÊÖ¤ë
+ template< typename Target, typename Source >
+ bool lexical_convert( Target& dest, const Source& src )
+ {
+ using namespace boost;
+
+ try
+ {
+ dest = lexical_cast<Target>(src);
+ return true;
+ }
+ catch( bad_lexical_cast )
+ {
+ return false;
+ }
+
+ } // lexical_convert
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_LEXICAL_CONVERT_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_LIST_FORMAT_HPP_
+#define GINTENLIB_INCLUDED_LIST_FORMAT_HPP_
+
+/*
+
+ <gintenlib/list_format.hpp>
+
+ list_format ¡§ ¥³¥ó¥Æ¥Ê¤Î¤ª¼ê·Ú¥¹¥È¥ê¡¼¥à½ÐÎÏ
+
+ Àë¸À¡§
+ template< typename Range >
+ unspecified list_format( const Range& src );
+
+ template< typename InIte >
+ unspecified list_format( const InIte& begin, const InIte& end );
+
+ template< typename Range, typename Pre, typename Delim, typename Post >
+ unspecified list_format( const Range& src, const Pre& pre, const Delim& delim, const Post& post );
+
+ template< typename InIte, typename Pre, typename Delim, typename Post >
+ unspecified list_format( const InIte& begin, const InIte& end, const Pre& pre, const Delim& delim, const Post& post );
+
+ µ¡Ç½¡§
+ Ǥ°Õ¤Î¥³¥ó¥Æ¥Ê¤äÇÛÎó¡Ê boost »ÈÍÑÈǤǤÏǤ°Õ¤Î range ¡Ë¤ò¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦²Ã¹©¤·¤Þ¤¹¡£
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï ( 1, 2, 3, 4 ) ¤Î¤è¤¦¤Ë½ÐÎϤµ¤ì¤Þ¤¹¤¬¡¢°ú¿ô¤ò»ØÄꤹ¤ë¤³¤È¤Ç¥¹¥¿¥¤¥ë¤ÏÊѹ¹¤Ç¤¤Þ¤¹¡£
+
+ »ÈÍÑÎ㡧
+ // v ¤ÏǤ°Õ¤Î¥³¥ó¥Æ¥Ê¡£( 1, 2, 3 ) ¤Î¤è¤¦¤Ëɽ¼¨¤µ¤ì¤Þ¤¹
+ cout << gintenlib::list_format(v) << endl;
+ // °ú¿ô¤ò»ØÄꤹ¤ì¤Ð¡¢[ 1 | 2 | 3 ] ¤Î¤è¤¦¤Êɽ¼¨¤Ë¤â¤Ç¤¤Þ¤¹
+ cout << gintenlib::list_format( v, "[ ", " | ", " ]" ) << endl;
+ // ¤Þ¤¿¡¢¥¤¥Æ¥ì¡¼¥¿¤ò»È¤Ã¤Æ½ÐÎÏÂоݤò»ØÄꤹ¤ë¤³¤È¤â½ÐÍè¤Þ¤¹¡£
+ // ¤³¤Î¾ì¹ç¤ÏµÕ½ç¤Îɽ¼¨¤Ë¤Ê¤ê¤Þ¤¹
+ cout << gintenlib::list_format( v.rbegin(), v.rend() ) << endl;
+
+ Ê䡧
+ ¡¦´ðËÜŪ¤Ë list_format ´Ø¿ô¤Ï¡¢¡ÖÌá¤êÃͤò¥¹¥È¥ê¡¼¥à¤Ëή¤¹¡×¤È¤¤¤¦»È¤¤Êý¤Î¤ß¤òÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£
+ ¡¦¤¿¤À¤·¡¢list_format ´Ø¿ô¤ÎÌá¤êÃÍ¤Ë boost::lexical_cast ¤òŬ±þ¤¹¤ë¤³¤È¤Ï²Äǽ¤Ç¤¹¡£
+ ¡¦¤Þ¤¿¡¢Ìá¤êÃͤò gintenlib::output_element ¥ª¥Ö¥¸¥§¥¯¥È¤Ë³ÊǼ¤¹¤ë¤³¤È¤â½ÐÍè¤Þ¤¹¡£
+ ¡¦¾åµ°Ê³°¤ÎÌÜŪ¤Ç»È¤Ã¤¿¾ì¹ç¡¢list_format ´Ø¿ô¤ÎÆ°ºî¤ÏÉÔÄê¤È¤Ê¤ê¤Þ¤¹¡£
+
+*/
+
+#include <boost/range.hpp>
+#include <boost/call_traits.hpp>
+
+namespace gintenlib
+{
+ // ¼ÂºÝ¤Ë¥¹¥È¥ê¡¼¥à¤Ëή¤¹¥¯¥é¥¹
+ template< typename InIte, typename Pre = const char*,
+ typename Delim = const char*, typename Post = const char* >
+ struct list_format_impl_
+ {
+ typedef typename boost::call_traits<InIte>::param_type inite_param_t;
+ typedef typename boost::call_traits<Pre>::param_type pre_param_t;
+ typedef typename boost::call_traits<Delim>::param_type delim_param_t;
+ typedef typename boost::call_traits<Post>::param_type post_param_t;
+
+ // constructor
+ list_format_impl_( inite_param_t begin, inite_param_t end,
+ pre_param_t pre, delim_param_t delim, post_param_t post )
+ : begin_(begin), end_(end), pre_(pre), delim_(delim), post_(post) {}
+
+ typename boost::call_traits<InIte>::value_type begin_, end_;
+ typename boost::call_traits<Pre>::value_type pre_;
+ typename boost::call_traits<Delim>::value_type delim_;
+ typename boost::call_traits<Post>::value_type post_;
+
+ // ½ÐÎϤμÂÁõ
+ // ¥Æ¥ó¥×¥ì¡¼¥È¤Ë¤è¤ê std::ostream ¤Ë¸Â¤é¤º½ÐÎϤǤ¤Þ¤¹
+ template<typename Stream>
+ friend Stream& operator<< ( Stream& os, const list_format_impl_& src )
+ {
+ // ¶õ¤Î¥ê¥¹¥È¤òɽ¼¨¤µ¤»¤è¤¦¤È¤·¤¿¾ì¹ç¡¢²¿¤âɽ¼¨¤µ¤ì¤Ê¤¤
+ if( src.begin_ == src.end_ ){ return os; }
+
+ // ɽ¼¨ËÜÂÎ
+ os << src.pre_;
+
+ InIte ite = src.begin_;
+ os << *ite;
+ for( ++ite; ite != src.end_; ++ite )
+ {
+ os << src.delim_ << *ite;
+ }
+
+ os << src.post_;
+
+ return os;
+
+ } // operator<< ( Stream&, const list_format_impl_& )
+
+ }; // struct list_format_impl_
+
+
+ // ´Ø¿ôËÜÂÎ
+
+ // ¥³¥ó¥Æ¥ÊÈÇ
+
+ // °ìÈÌ·Á¡£Ç¤°Õ¤Î pre, delim, post ¤Ë´Ø¤·¤Æ
+ // os << pre << Í×ÁÇ£± << delim << Í×ÁÇ£² << ... << delim << Í×ÁÇ£î << end;
+ // ¤È¤¤¤¦¥¤¥á¡¼¥¸¤Ç½ÐÎϤµ¤ì¤ë¡£
+ template< typename Range, typename Pre, typename Delim, typename Post >
+ inline const list_format_impl_< typename boost::range_iterator<const Range>::type, Pre, Delim, Post >
+ list_format
+ ( const Range& src, const Pre& pre, const Delim& delim, const Post& post )
+ {
+ using namespace boost;
+
+ return list_format_impl_< typename range_iterator<const Range>::type, Pre, Delim, Post >
+ ( begin(src), end(src), pre, delim, post );
+ }
+
+ // ¾ÊάÈÇ¡£( Í×ÁÇ£±, Í×ÁÇ£², ... , Í×ÁÇ£î ) ¤È¤¤¤¦´¶¤¸¤Ë½ÐÎÏ
+ template< typename Range >
+ inline const list_format_impl_< typename boost::range_iterator<const Range>::type >
+ list_format( const Range& src )
+ {
+ using namespace boost;
+
+ return list_format_impl_< typename range_iterator<const Range>::type >
+ ( begin(src), end(src), "( ", ", ", " )" );
+ }
+
+
+ // ¥¤¥Æ¥ì¡¼¥¿ÈÇ
+
+ // °ìÈÌ·Á
+ template< typename InIte, typename Pre, typename Delim, typename Post >
+ inline const list_format_impl_<InIte, Pre, Delim, Post>
+ list_format
+ ( const InIte& begin, const InIte& end, const Pre& pre, const Delim& delim, const Post& post )
+ {
+ return list_format_impl_<InIte, Pre, Delim, Post>( begin, end, pre, delim, post );
+ }
+
+ // ¾ÊάÈÇ
+ template< typename InIte >
+ inline const list_format_impl_<InIte>
+ list_format( const InIte& begin, const InIte& end )
+ {
+ return list_format_impl_<InIte>( begin, end, "( ", ", ", " )" );
+ }
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_LIST_FORMAT_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_
+#define GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_
+
+/*
+
+ <gintenlib/list_formatter.hpp>
+
+ list_formatter ¡§ ¥Õ¥¡¥ó¥¯¥¿ÈÇ list_format¡Êconst char* ÈÇ¡Ë
+
+ Àë¸À¡§
+ template< typename Elem >
+ struct basic_list_formatter
+ {
+ explicit basic_list_formatter
+ (
+ gintenlib_param_t(Elem) pre_ = "( ",
+ gintenlib_param_t(Elem) delim_ = ", ",
+ gintenlib_param_t(Elem) post_ = " )"
+ );
+
+ typedef gintenlib_value_t(Elem) element_type;
+ // ¥á¥ó¥Ð¡ÖÊÑ¿ô¡×¡¢¼«Í³¤Ë³°Éô¤«¤é¥¢¥¯¥»¥¹¤Ç¤¤ë
+ element_type pre, delim, post;
+
+ // ½ÐÎÏÈϰϤò»ØÄꤷ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë¤¹¤ë
+ template< typename InIte >
+ list_format_impl_< InIte, Elem, Elem, Elem >
+ operator()( const InIte& begin, const InIte& end ) const;
+
+ // ½ÐÎÏÈϰϤò range ¤Ç»ØÄê
+ template< typename Range >
+ list_format_impl_< gintenlib_const_ite_of(Range), Elem, Elem, Elem >
+ operator()( const Range& src ) const;
+
+ // ostream_iterator ¤Î¤è¤¦¤Ë¿¶Éñ¤¦¥¤¥Æ¥ì¡¼¥¿¤òÀ½ºî¡£
+ // ¥¤¥Æ¥ì¡¼¥¿¤¬´û¤ËÀ½ºî¤µ¤ì¤Æ¤¤¤¿¾ì¹ç¤Ï¡¢¤¤¤Ã¤¿¤ó¥ê¥¹¥È¤¬ÊĤ¸¤é¤ì¤ë
+ template< typename Stream >
+ iterator<Stream> make_iterator( Stream& os ) const;
+
+ template< typename Stream >
+ struct iterator
+ : std::iterator< std::output_iterator_tag, void, void, void, void >
+ {
+ iterator( const basic_list_formatter& formatter, Stream& os );
+ iterator( const iterator& src );
+
+ ~iterator();
+
+ iterator& operator=( const iterator& src );
+ iterator& swap( iterator& other );
+
+ template< typename T >
+ iterator& operator=( const T& val );
+
+ iterator& close();
+
+ iterator& operator*(){ return *this; }
+ iterator& operator++(){ return *this; }
+ iterator& operator++(int){ return *this; }
+
+ }; // struct iterator
+
+ }; // struct basic_list_formatter
+
+ typedef basic_list_formatter<const char*> list_formatter;
+
+ µ¡Ç½¡§
+ list_format(v) ¤ä list_format( begin, end ) ¤È»È¤¦Éôʬ¤Ç¡¢Âå¤ï¤ê¤Ë»ÈÍѤǤ¤ë¥Õ¥¡¥ó¥¯¥¿¡£
+
+ list_formatter formatter( pre, delim, post );
+ cout << formatter(v) << endl;
+
+ ¤³¤Î¥³¡¼¥É¤Î¼Â¹Ô·ë²Ì¤Ï cout << list_format( v, pre, delim, post ) << endl; ¤ÈÅù²Á¡£
+ ͽ¤á pre, delim, post ¤ÎÀßÄê¤ò¤·¤Æ¤ª¤¤¤Æ»È¤¤¤Þ¤ï¤·¤¿¤¤¾ì¹ç¤Ë»ÈÍѤǤ¤ë¡£
+
+ ¤â¤¦°ì¤Ä¤Îµ¡Ç½¤È¤·¤Æ¡¢make_iterator() ¥á¥ó¥Ð´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ç½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤ò¹½ÃۤǤ¤ëµ¡Ç½¤â¤¢¤ê¡¢
+
+ cout << formatter(v);
+ cout << formatter( v.begin(), v.end() );
+ copy( v.begin(), v.end(), formatter.make_iterator(cout) );
+
+ ¤³¤Î»°¤Ä¤Îʸ¤Î¼Â¹Ô·ë²Ì¤Ï¡¢¤É¤ì¤âÅù¤·¤¤¡£
+
+ »ÈÍÑÎ㡧
+ // ¹½ÃÛ¤·¤Æ
+ gintenlib::list_formatter formatter( "[ ", " | ", " ]\n" );
+
+ // Ǥ°Õ¤Î¥³¥ó¥Æ¥Ê v ¤ËÂФ·¡¢Å¬ÍѤ¹¤ë
+ cout << formatter(v);
+ // µÕ½ç¤Ëɽ¼¨¤ò¤·¤Æ¤ß¤ë
+ cout << formatter( v.rbegin(), v.rend() );
+ // µÕ½ç¤Ëɽ¼¨¤¹¤ë¤Ë¤Ï¡¢¤³¤¦½ñ¤¤¤Æ¤â¤è¤¤
+ reverse_copy( v.begin(), v.end(), formatter.ite(cout) );
+
+ Ê䡧
+ ¡¦pre, delim, post ¤Ï const char* ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+ Ǥ°ÕÍ×ÁǤò³ÊǼ¤·¤¿¤¤¾ì¹ç¤Ï¡¢list_formatter_ex ¤òÍѤ¤¤ë¡£
+ ¡¦operator() ¤ÎŬÍÑ·ë²Ì¤Î¼è¤ê°·¤¤¤Ï¡¢ list_format ´Ø¿ô¤ÎÌá¤êÃͤÈƱ¤¸¤è¤¦¤Ë°·¤¦¡£
+ ¡¦½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤ò»ÈÍѤ¹¤ë¾ì¹ç¤ÎÃí°Õ»ö¹à¡§
+ ¡¦pre Í×ÁǤϡֺǽé¤ÎÍ×ÁǤ¬¼ÂºÝ¤Ë½ÐÎϤµ¤ì¤ëľÁ°¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
+ ¡¦delim Í×ÁǤϡÖÆó²óÌܰʹߤÎÍ×ÁǤ¬½ÐÎϤµ¤ì¤ëľÁ°¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
+ ¡¦post Í×ÁǤϡ֥³¥Ô¡¼¤ò´Þ¤á¡¢Á´¤Æ¤Î¥¤¥Æ¥ì¡¼¥¿¤¬ÇË´þ¤µ¤ì¤¿¤È¤¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
+ ¤¿¤À¤·¡¢Ì¤¤À pre ¤¬½ÐÎϤµ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢post ¤â½ÐÎϤµ¤ì¤Ê¤¤¡£
+ ¡¦¤â¤·Á´¤Æ¤Î¥¤¥Æ¥ì¡¼¥¿¤¬ÇË´þ¤µ¤ì¤ëÁ°¤Ë¿·¤¿¤Ê¥¤¥Æ¥ì¡¼¥¿¤òÀ½ºî¤·¤¿¾ì¹ç¡¢
+ ¤½¤Î»þÅÀ¤Ç post Í×ÁǤ¬½ÐÎϤµ¤ì¡¢¡Ö²¿¤â½ÐÎϤµ¤ì¤Æ¤¤¤Ê¤¤¡×¾õÂ֤ˤʤ롣
+
+*/
+
+#include <iterator>
+#include <cassert>
+#include <algorithm> // for swap()
+
+#include <boost/range.hpp>
+#include <boost/call_traits.hpp>
+
+#include "list_format.hpp"
+
+namespace gintenlib
+{
+ template< typename Elem >
+ class basic_list_formatter
+ {
+ typedef typename boost::call_traits<Elem>::param_type param_type;
+
+ public:
+ typedef typename boost::call_traits<Elem>::value_type element_type;
+
+ basic_list_formatter()
+ : pre("( "), delim(", "), post(" )"), iterator_count_(0) {}
+
+ explicit basic_list_formatter
+ ( param_type pre_, param_type delim_, param_type post_ )
+ : pre(pre_), delim(delim_), post(post_), iterator_count_(0) {}
+
+ // ¥á¥ó¥ÐÊÑ¿ô¤Ê¤Î¤Ç¡¢¼«Í³¤Ë¥¢¥¯¥»¥¹¤Ç¤¤ë¡£
+ element_type pre, delim, post;
+
+ // ½ÐÎÏÈϰϤò¥¤¥Æ¥ì¡¼¥¿¤Ç»ØÄꤷ¤Æ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë
+ template< typename InIte >
+ list_format_impl_< InIte, Elem, Elem, Elem >
+ operator()( const InIte& begin, const InIte& end ) const
+ {
+ return list_format_impl_< InIte, Elem, Elem, Elem >( begin, end, pre, delim, post );
+ }
+ // ½ÐÎÏÈϰϤò range ¤Ç»ØÄꤷ¤Æ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë
+ template< typename Range >
+ list_format_impl_< typename boost::range_iterator<const Range>::type, Elem, Elem, Elem >
+ operator()( const Range& src ) const
+ {
+ return list_format_impl_< typename boost::range_iterator<const Range>::type, Elem, Elem, Elem >
+ ( boost::begin(src), boost::end(src), pre, delim, post );
+ }
+
+ // ¥¤¥Æ¥ì¡¼¥¿
+ template< typename Stream >
+ struct iterator
+ : std::iterator< std::output_iterator_tag, void, void, void, void >
+ {
+ iterator( const basic_list_formatter& formatter, Stream& os )
+ : formatter_(&formatter), os_(&os)
+ {
+ // ½ÐÎϤ¬¡ÖÊĤ¸¤Æ¡×¤Ê¤¤¤Ê¤é¡¢ÊĤ¸¤ë
+ close();
+
+ // ¤³¤Î»þÅÀ¤Ç¥«¥¦¥ó¥È¤ÏÉé
+ --formatter_->iterator_count_;
+ }
+
+ iterator( const iterator& src )
+ : formatter_(src.formatter_), os_(src.os_)
+ {
+ if( formatter_->iterator_count_ > 0 )
+ {
+ ++formatter_->iterator_count_;
+ }
+ else if( formatter_->iterator_count_ < 0 )
+ {
+ --formatter_->iterator_count_;
+ }
+ else
+ {
+ assert( !"basic_list_formatter::iterator::iterator(const iterator&) : sould not get here." );
+ }
+ }
+
+ ~iterator()
+ {
+ if( formatter_->iterator_count_ > 0 )
+ {
+ // count ¤¬Àµ <==> ´û¤Ë²¿¤«½ÐÎϤµ¤ì¤Æ¤¤¤ë
+ if( --formatter_->iterator_count_ == 0 )
+ {
+ // count ¤¬ 0 ¤Ë¤Ê¤Ã¤¿ <==> ¤â¤¦Â¾¤Î¥¤¥Æ¥ì¡¼¥¿¤Ï̵¤¤
+ *os_ << formatter_->post;
+ }
+ }
+ else if( formatter_->iterator_count_ < 0 )
+ {
+ ++formatter_->iterator_count_;
+ }
+ else
+ {
+ assert( !"basic_list_formatter::iterator::~iterator() : sould not get here." );
+ }
+ }
+
+ iterator& operator=( const iterator& src )
+ {
+ iterator temp(src);
+ swap(temp);
+ return *this;
+ }
+ void swap( iterator& other )
+ {
+ using std::swap;
+ swap( formatter_, other.formatter_ );
+ swap( os_, other.os_ );
+ }
+ friend void swap( iterator& one, iterator& other )
+ {
+ one.swap(other);
+ }
+
+ // ¼ÂºÝ¤Î½ÐÎÏ
+ template< typename T >
+ iterator& operator=( const T& val )
+ {
+ if( formatter_->iterator_count_ > 0 )
+ {
+ *os_ << formatter_->delim << val;
+ }
+ else if( formatter_->iterator_count_ < 0 )
+ {
+ *os_ << formatter_->pre << val;
+ formatter_->iterator_count_ = -formatter_->iterator_count_;
+ }
+ else
+ {
+ assert( !"basic_list_formatter::iterator::operator=(const T&) : sould not get here." );
+ }
+ return *this;
+ }
+
+ // ¡Ö½ÐÎϤòÊĤ¸¤ë¡×
+ iterator& close()
+ {
+ // ¥«¥¦¥ó¥È¤¬Àµ <==> ½ÐÎϤ¬¡ÖÊĤ¸¤Æ¡×¤Ê¤¤
+ if( formatter_->iterator_count_ > 0 )
+ {
+ // ÊĤ¸¤ë
+ *os_ << formatter_->post;
+ // ¡Ö̤½ÐÎϡפؤÈÀßÄê
+ formatter_->iterator_count_ = -formatter_->iterator_count_;
+ }
+ return *this;
+ }
+
+ // »²¾È³°¤·¤â¡¢Á°ÃÖ¡¿¸åÃÖ¥¤¥ó¥¯¥ê¥á¥ó¥È¤â¡¢²¿¤â¤·¤Ê¤¤
+ iterator& operator*(){ return *this; }
+ iterator& operator++(){ return *this; }
+ iterator& operator++(int){ return *this; }
+
+ private:
+ const basic_list_formatter* formatter_;
+ Stream* os_;
+
+ }; // struct iterator
+
+ template< typename Stream >
+ friend struct iterator;
+
+ // ½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤òºî¤ë
+ template< typename Stream >
+ iterator<Stream> make_iterator( Stream& os ) const
+ {
+ return iterator<Stream>( *this, os );
+ }
+
+ private:
+ mutable int iterator_count_;
+
+ }; // struct basic_list_formatter
+
+ typedef basic_list_formatter<const char*> list_formatter;
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_MATH_HPP_
+#define GINTENLIB_INCLUDED_MATH_HPP_
+
+/*
+ <gintenlib/math.hpp>
+
+ math ¡§ M_PI ¤È¤¤¤Ã¤¿Äê¿ô¥Þ¥¯¥í¤ò³Î¼Â¤Ë #define ¤·¤Æ¤¯¤ì¤ë <cmath> ¥Ø¥Ã¥À
+
+ µ¡Ç½¡§
+ <cmath> ¥Ø¥Ã¥À¤Ï¼ÂÁõ¤Ë¤è¤Ã¤Æ³Æ¼ï¿ô³ØÄê¿ô¤¬ define ¤µ¤ì¤Ê¤¤¾ì¹ç¤¬¤¢¤ë¤Î¤Ç¡¢
+ ¤½¤¦¤¤¤¦¾ì¹ç¤ËÂбþ¤¹¤ë¤¿¤á¤Î¥Ø¥Ã¥À¤Ç¤¹¡£
+ ³ÆÄê¿ô¤Î°ÕÌ£¤Ï¤½¤ì¤¾¤ì¤Î¥³¥á¥ó¥È¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+*/
+
+#include <cmath>
+
+// ¼«Á³Âпô¤ÎÄì e
+#ifndef M_E
+#define M_E 2.71828182845904523536
+#endif
+
+// log2(e)
+#ifndef M_LOG2E
+#define M_LOG2E 1.44269504088896340736
+#endif
+
+// log10(e)
+#ifndef M_LOG10E
+#define M_LOG10E 0.434294481903251827651
+#endif
+
+// ln(2)
+#ifndef M_LN2
+#define M_LN2 0.693147180559945309417
+#endif
+
+// ln(10)
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402
+#endif
+
+// ±ß¼þΨ¦Ð
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+// ¦Ð / 2
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#endif
+
+// ¦Ð / 4
+#ifndef M_PI_4
+#define M_PI_4 0.785398163397448309616
+#endif
+
+// 1 / ¦Ð
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
+
+// 2 / ¦Ð
+#ifndef M_2_PI
+#define M_2_PI 0.636619772367581343076
+#endif
+
+// 2 / sqrt(¦Ð)
+#ifndef M_2_SQRTPI
+#define M_2_SQRTPI 1.12837916709551257390
+#endif
+
+// sqrt(2)
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880
+#endif
+
+// sqrt(1/2)
+#ifndef M_SQRT1_2
+#define M_SQRT1_2 0.707106781186547524401
+#endif
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_MATH_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_MOVE_PTR_HPP_
+#define GINTENLIB_INCLUDED_MOVE_PTR_HPP_
+
+/*
+
+ <gintenlib/move_ptr.hpp>
+
+ move_ptr ¡§ ½ê͸¢°ÜÆ°¼°¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿
+
+ Àë¸À¡§
+ template<typename T, typename Deleter>
+ struct move_ptr
+ {
+ // ´ðËÜŪ¤Ê¥á¥½¥Ã¥É¤Ï auto_ptr ¤ÈƱ¤¸¤Ê¤Î¤Ç¾Êά
+
+ // ¥Ç¥ê¡¼¥¿¤Î·¿
+ typedef Deleter deleter;
+
+ // ¥Ý¥¤¥ó¥¿¡Ê¤È¥Ç¥ê¡¼¥¿¡Ë¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
+ explicit move_ptr( T* p_, const Deleter& del_ = Deleter() );
+
+ // release ¤¹¤ë¤ÈƱ»þ¤Ë deleter ¤ò¼èÆÀ¤¹¤ë
+ // Ä̾ï¤Î release ´Ø¿ô¤âÅöÁ³¤¢¤ê¤Þ¤¹
+ T* release( Deleter& del_ );
+
+ // deleter ¤ò¼èÆÀ¤¹¤ë
+ Deleter get_deleter() const;
+
+ };
+
+ µ¡Ç½¡§
+ std::auto_ptr ¤ò¡¢Ç¤°Õ¤Î¥Ç¥ê¡¼¥¿¤ò»ØÄê¤Ç¤¤ë¤è¤¦³ÈÄ¥¤·¤¿½ê͸¢°ÜÆ°¼°¥Ý¥¤¥ó¥¿¤Ç¤¹¡£
+ ¤½¤ì¤ÈƱ»þ¤Ë swap ¸Æ¤Ó½Ð¤·¤â½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+ ¤½¤ì°Ê³°¤Ï¡¢ºÙ¤«¤¤¤È¤³¤í¤Þ¤Ç std::auto_ptr ¤ÈƱ¤¸¤è¤¦¤Ë¿¶Éñ¤¦¤è¤¦¹©Éפ·¤Æ¤¤¤Þ¤¹¡£
+ ¤¬¡¢¥Ç¥ê¡¼¥¿¤¬Ç¤°Õ¤Ë¤Ê¤Ã¤¿ÅÔ¹ç¾å¡¢Îã³°°ÂÁ´À¤Ç¤Ï¼ã´³Àȼå¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤Æ¤¤¤Þ¤¹¡£
+ ¤Ê¤ª¡¢¥Ç¥ê¡¼¥¿¤È¤·¤Æ»È¤¨¤ë¤Î¤Ï¡¢¡Ö¥Ç¥Õ¥©¥ë¥È¹½ÃÛ²Äǽ¡×¤Ç¡Ö¥³¥Ô¡¼¤Ç¤¤ë¡×¡Ö¥Õ¥¡¥ó¥¯¥¿¡×¡£
+ Îã³°°ÂÁ´À¤ò¹Í¤¨¤ë¤È¡Ö¥Ç¥Õ¥©¥ë¥È¹½ÃÛ»þ¡×¡Ö swap »þ¡×¤ËÎã³°¤òÅꤲ¤Ê¤¤¡¢¤È¤¤¤¦¾ò·ï¤âɬÍפǤ¹¡£
+ ¤Þ¤¿¡¢¥Ç¥Õ¥©¥ë¥È¹½ÃÛ¤µ¤ì¤¿¥Ç¥ê¡¼¥¿¤ËÂФ·¤Æ´Ø¿ô¸Æ½Ð¤·¤¬¹Ô¤ï¤ì¤ë¤³¤È¤Ïͤê¤Þ¤»¤ó¡£
+ ¤Ê¤Î¤Ç¡¢´Ø¿ô¥Ý¥¤¥ó¥¿¤ò¥Ç¥ê¡¼¥¿¤È¤·¤Æ»È¤¦¤³¤È¤âÉáÄ̤ˣϣˡ£
+
+*/
+
+#include <algorithm>
+#include <boost/compressed_pair.hpp>
+#include <boost/utility/value_init.hpp>
+#include "deleter.hpp"
+#include "bool_comparable.hpp"
+
+namespace gintenlib
+{
+ namespace detail
+ {
+ // ´Ø¿ô¤ÎÃÍÊÖ¤·¤Î¤¿¤á¤Î¡¢¤Á¤ç¤Ã¤È¤·¤¿¹©É×
+ template< typename T, typename Deleter >
+ struct move_ptr_ref_
+ {
+ typedef boost::compressed_pair<T*, Deleter> pair_type;
+ pair_type pair_;
+
+ template< typename U, typename D >
+ move_ptr_ref_( const move_ptr_ref_<U, D>& src )
+ : pair_( src.pair_.first(), src.pair_.second() ) {}
+
+ template< typename U, typename D >
+ explicit move_ptr_ref_( const boost::compressed_pair<U, D>& src )
+ : pair_( src.first(), src.second() ) {}
+
+ template< typename U, typename D >
+ move_ptr_ref_( const U& first, const D& second ) : pair_( first, second ) {}
+
+ };
+
+ } // namespace detail
+
+ // ËÜÂÎ
+ template< typename T, typename Deleter = ::gintenlib::deleter >
+ struct move_ptr : bool_comparable< move_ptr<T, Deleter> >
+ {
+ template<typename U, typename D>
+ friend class move_ptr;
+
+ typedef T element_type;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef Deleter deleter;
+
+ // ¥Ç¥Õ¥©¥ë¥È¥³¥ó¥¹¥È¥é¥¯¥¿
+ move_ptr() : pair_( 0, deleter() ) {}
+
+ // ¥Ý¥¤¥ó¥¿¡Ê¤È¥Ç¥ê¡¼¥¿¡Ë¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
+ explicit move_ptr( pointer p_, const deleter& del_ = deleter() )
+ : pair_( p_, del_ ) {}
+
+
+ // ½ê͸¢°ÜÆ°¥³¥ó¥¹¥È¥é¥¯¥¿
+ move_ptr( move_ptr& src ) : pair_( 0, deleter() )
+ {
+ swap(src);
+ }
+ // ¾¤Î move_ptr ¤«¤é¤Î½ê͸¢°ÜÆ°
+ // ·¿¤ò¤Þ¤¿¤¤¤À swap ¤¬ÉÔ²Äǽ¤Ê°Ê¾å¡¢Èù̯¤ËÎã³°°ÂÁ´¤¸¤ã¤Ê¤¤¤Î¤ÇÃí°Õ
+ template< typename U, typename D >
+ move_ptr( move_ptr<U, D>& src ) : pair_( src.p(), src.del() )
+ {
+ src.release();
+ }
+
+ // ¥Ç¥¹¥È¥é¥¯¥¿
+ ~move_ptr()
+ {
+ if( p() )
+ {
+ del()( p() );
+ }
+ }
+
+
+ // swap ( for operator= )
+ void swap( move_ptr& other )
+ {
+ pair_.swap( other.pair_ );
+ }
+ friend void swap( move_ptr& one, move_ptr& another ) // never throws
+ {
+ one.swap( another );
+ }
+
+ // move assignment
+ move_ptr& operator=( move_ptr& src )
+ {
+ move_ptr temp(src);
+ this->swap( temp );
+ return *this;
+ }
+ template< typename U, typename D >
+ move_ptr& operator=( move_ptr<U, D>& src )
+ {
+ move_ptr temp(src);
+ this->swap( temp );
+ return *this;
+ }
+
+ reference operator*() const
+ {
+ using namespace std;
+ assert( p() != 0 );
+ return *p();
+ }
+ pointer operator->() const
+ {
+ using namespace std;
+ assert( p() != 0 );
+ return p();
+ }
+
+ // get pointer
+ pointer get() const { return p(); }
+ // mem_fn support
+ friend T* get_pointer( const move_ptr& ptr )
+ {
+ return ptr.get();
+ }
+
+ // release pointer
+ // ¥Ý¥¤¥ó¥¿¤ò¥ê¥ê¡¼¥¹¤·¡¢¥Ç¥ê¡¼¥¿¤ò½é´ü²½¤·¤Þ¤¹¡£
+ // deleter ¤Î swap ¤¬Îã³°¤òÅꤲ¤Ê¤±¤ì¤ÐÎã³°°ÂÁ´¤Ç¤¹¡£
+ pointer release()
+ {
+ pointer ptr = 0;
+ boost::value_initialized<deleter> d_;
+ deleter& d = d_;
+
+ using std::swap;
+ swap( p(), ptr );
+ swap( del(), d );
+
+ return ptr;
+ }
+ // ¥Ý¥¤¥ó¥¿¤ò¥ê¥ê¡¼¥¹¤·¡¢¥Ç¥ê¡¼¥¿¤â¼èÆÀ¡£
+ // ÅϤµ¤ì¤ë»²¾È¤Ë²¿¤¬ÂåÆþ¤µ¤ì¤Æ¤¤¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£
+ // Îã³°°ÂÁ´À¤ò¹Íθ¤· swap ¤Ë¤è¤ë¼ÂÁõ¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£
+ pointer release( deleter& del_ )
+ {
+ pointer ptr = 0;
+ boost::value_initialized<deleter> d_;
+ deleter& d = d_;
+
+ using std::swap;
+ swap( del(), del_ );
+
+ swap( p(), ptr );
+ swap( del(), d );
+
+ return ptr;
+ /*
+ del_ = del();
+
+ return release();
+ */
+ }
+
+ deleter get_deleter() const
+ {
+ return del();
+ }
+ friend deleter get_deleter( const move_ptr& target )
+ {
+ return target.get_deleter();
+ }
+
+ void reset()
+ {
+ move_ptr temp;
+ this->swap(temp);
+ }
+ void reset( T* p_, const deleter& del_ = deleter() )
+ {
+ move_ptr temp( p_, del_ );
+ this->swap( temp );
+ }
+
+
+ bool operator!() const // never throws
+ {
+ return !p();
+ }
+
+ bool operator==( const move_ptr& other ) const // never throws
+ {
+ return p() == other.p();
+ }
+ bool operator!=( const move_ptr& other ) const // never throws
+ {
+ return p() != other.p();
+ }
+
+ template<typename U, typename D>
+ bool operator==( const move_ptr<U, D>& other ) const // never throws
+ {
+ return p() == other.p();
+ }
+ template<typename U, typename D>
+ bool operator!=( const move_ptr<U, D>& other ) const // never throws
+ {
+ return p() != other.p();
+ }
+
+ private:
+ typedef typename detail::move_ptr_ref_<T, Deleter>::pair_type pair_type;
+ pair_type pair_;
+
+ pointer& p()
+ {
+ return pair_.first();
+ }
+ const pointer& p() const
+ {
+ return pair_.first();
+ }
+
+ deleter& del()
+ {
+ return pair_.second();
+ }
+ const deleter& del() const
+ {
+ return pair_.second();
+ }
+
+ public:
+ // ÃͤǤμõ¤±ÅϤ·¤Î¤¿¤á¤Î¡¢¤Á¤ç¤Ã¤È¤·¤¿¥Æ¥¯
+ move_ptr( const detail::move_ptr_ref_<T, Deleter>& src ) : pair_(src.pair_) {}
+
+ move_ptr& operator=( const detail::move_ptr_ref_<T, Deleter>& src )
+ {
+ move_ptr temp(src);
+ this->swap( temp );
+ return *this;
+ }
+
+ template<typename U, typename D>
+ operator detail::move_ptr_ref_<U, D>()
+ {
+ detail::move_ptr_ref_<U, D> temp( pair_ );
+ release();
+ return temp;
+ }
+
+ // pointer casts
+ template<typename U>
+ friend move_ptr<U, deleter> static_pointer_cast( move_ptr& t )
+ {
+ move_ptr<U, deleter> temp( static_cast<U*>( t.p() ), t.del() );
+ t.release();
+ return temp;
+ }
+ template<typename U>
+ friend move_ptr<U, deleter> dynamic_pointer_cast( move_ptr& t )
+ {
+ move_ptr<U, deleter> temp( dynamic_cast<U*>( t.p() ), t.del() );
+ t.release();
+ return temp;
+ }
+ template<typename U>
+ friend move_ptr<U, deleter> const_pointer_cast( move_ptr& t )
+ {
+ move_ptr<U, deleter> temp( const_cast<U*>( t.p() ), t.del() );
+ t.release();
+ return temp;
+ }
+
+ }; // class move_ptr<T>
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_MOVE_PTR_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_NEW__HPP_
+#define GINTENLIB_INCLUDED_NEW__HPP_
+
+/*
+
+ <gintenlib/new_.hpp>
+
+ new_ ¡§ ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿ÈÇ new ±é»»»Ò
+
+ Àë¸À¡§
+ template<typename T>
+ struct ptr
+ {
+ typedef boost::shared_ptr<T> type;
+ };
+
+ template<typename T>
+ inline typename ptr<T>::type new_();
+
+ template< typename T, typename Arg1, ... , typename ArgN >
+ inline typename ptr<T>::type new_( const Arg1& arg1, ... , const ArgN& argN );
+
+ class new_core_access;
+
+ template<typename Derived>
+ struct enable_static_new_;
+
+ // ¤Û¤«¤Ë¡¢new_ ¤ÈƱ¤¸µ¡Ç½¤ò»ý¤Ã¤¿¥Õ¥¡¥ó¥¯¥¿¡¢ new_ptr<T> ¤¬Â¸ºß¤¹¤ë¡£
+
+ µ¡Ç½¡§
+ T ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò new ±é»»»Ò¤ÇÀ½ºî¤·¡¢¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ë³ÊǼ¤·¤ÆÊÖ¤¹´Ø¿ô¡£
+ ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Î·¿¤Ï ptr<T>::type ¤ÇÄ´¤Ù¤ë¤³¤È¤¬½ÐÍè¤ë¡£¤³¤Î·¿¤Ï boost::shared_ptr<T> ¤ËÅù¤·¤¤¡£
+ ¤³¤Î´Ø¿ô¤«¤é¤Î new ¥¢¥¯¥»¥¹¤Ï¡¢Á´¤Æ new_core_access ¹½Â¤ÂΤòÄ̤·¤Æ¹Ô¤ï¤ì¤ë¡£¤è¤Ã¤Æ
+ friend class gintenlib::new_core_access;
+ ¤È¤·¤¿¾å¤Ç¥³¥ó¥¹¥È¥é¥¯¥¿¤ò private Éôʬ¤Ë¤ª¤±¤Ð¡¢new_ ¤òÄ̤¸¤Æ¤Î¤ß¹½ÃۤǤ¤ë¥¯¥é¥¹¤Ë¤Ê¤ë¡£
+ ¤â¤· private ¥³¥ó¥¹¥È¥é¥¯¥¿¤ÎÁ´¤Æ¤ò¸ø³«¤¹¤ë¤Î¤¬·ù¤Ê¤é¤Ð¡¢
+ class hoge
+ : public gintenlib::enable_static_new_<hoge>
+ {
+ friend class gintenlib::new_core_access;
+ static boost::shared_ptr<hoge> new_( ¥Ñ¥é¥á¡¼¥¿ ); // °Ê²¼Î¬
+ ¤Î¤è¤¦¤Ë¡¢ enable_static_new_ ¥Æ¥ó¥×¥ì¡¼¥È¥¯¥é¥¹¤Ë¥¯¥é¥¹Ì¾¤òÅϤ·¤Æ public ·Ñ¾µ¤·¡¢
+ ɬÍפÊʬ¤À¤± new_ ¤È¤¤¤¦Ì¾Á°¤ÎÀÅŪ¥á¥ó¥Ð´Ø¿ô¤ò¸ø³«¤¹¤ì¤Ð¡¢new_ ¤Ë¤è¤Ã¤ÆÄêµÁ¤µ¤ì¤¿¤â¤Î¤Î¤ß¸ø³«¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£
+ ¤³¤ÎºÝ¡¢ new_ ´Ø¿ô¤ÎÌá¤êÃͤϡ¢ptr<T>::type ¤ËÌÀ¼¨ÅªÊÑ´¹¤¹¤ë¤³¤È¤µ¤¨½ÐÍè¤ì¤ÐǤ°Õ¤Ç¤¢¤ë¡£
+
+ »ÈÍÑÎ㡧
+ boost::shared_ptr<hoge> p = gintenlib::new_<hoge>( 1, 2, 3 );
+ // boost::shared_ptr<hoge> p( new hoge( 1, 2, 3 ) ); ¤ÈƱ¤¸
+
+ ÍøÅÀ¡§
+ ¤³¤Î new_ ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦ÍøÅÀ¤Ï´ö¤Ä¤«¤¢¤ê¤Þ¤¹¡£
+ ¤Þ¤ººÇ¤âñ½ã¤Ê¤Î¤¬¥³¡¼¥ÉÎ̤κ︺¤Ç¡¢Í½¤á using Àë¸À¤·¤Æ¤ª¤¯¤³¤È¤Ç¥³¡¼¥ÉÎ̤κ︺¤¬ÁÀ¤¨¤Þ¤¹¡£
+ ¼¡¤ËÎã³°°ÂÁ´À¡£°ì¤Ä¤Î¥¹¥Æ¡¼¥È¥á¥ó¥È¤ËÊ£¿ô¤Î new ±é»»»Ò¤ò½ñ¤¯¤È¡¢É¾²Á½ç¤Ë¤è¤Ã¤Æ¤Ï¥á¥â¥ê¥ê¡¼¥¯¤¬È¯À¸¤¹¤ë²ÄǽÀ¤¬¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤Î´Ø¿ô¤ò»È¤¨¤ÐËɻߤǤ¤Þ¤¹¡£
+ ºÇ¸å¤Ë¡¢new_ °Ê³°¤«¤é¥ª¥Ö¥¸¥§¥¯¥È¤ò¹½ÃÛ¤·¤Ê¤¤¤è¤¦¤Ë¥¢¥¯¥»¥¹¤òÀ©¸Â¤Ç¤¤ëÅÀ¡£¼ÂºÝ¤Ë¤Ï¥¹¥¿¥Ã¥¯¤Ë¤âÃÖ¤±¤ë¤è¤¦¤Ë¤·¤¿¤Û¤¦¤¬ÍøÊØÀ¤Ï¹â¤¤¤Î¤Ç¸Ä¿ÍŪ¤Ë¤Ï¥ª¥¹¥¹¥á¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡£
+ °ìÊý¤Ç¡¢ÉáÄ̤εˡ¤È°ã¤¦Ê¬Æɤߤˤ¯¤¤¡¢¥³¥ó¥Ñ¥¤¥é¤Ë¤è¤Ã¤Æ¤Ï;·×¤Ê¥³¥Ô¡¼¤¬È¯À¸¤¹¤ë¡¢¤½¤â¤½¤â enable_if ¤¬Æ°¤«¤Ê¤¤¤È¤É¤¦¤·¤è¤¦¤â¤Ê¤¤¡¢¤È¤¤¤¦¥Ç¥á¥ê¥Ã¥È¤â¤¢¤ê¤Þ¤¹¡£
+ Æä˺Ǹå¤Î¥¢¥¯¥»¥¹À©¸Â¤ò¹Ô¤¦¾ì¹ç¤Ë¤Ï¡¢¤½¤ì¤é¤Î¥Ç¥á¥ê¥Ã¥È¤â¹Íθ¤·¤¿¾å¤Ç¿µ½Å¤Ë·è¤á¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£
+
+ È÷¹Í¡§
+ °ú¿ô¤Ï const& ¤ÇÅϤµ¤ì¤Þ¤¹¡£Èóconst»²¾È¤òÅϤ·¤¿¤¤¾ì¹ç¤Ë¤Ï boost::ref ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+*/
+
+#include "shared_ptr.hpp"
+#include "enable_if.hpp"
+#include <boost/preprocessor.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+// °ú¿ô¤ÎºÇÂçÃÍ
+#ifndef GINTENLIB_ARG_COUNT
+#define GINTENLIB_ARG_COUNT 10
+#endif
+
+namespace gintenlib
+{
+ // new_ ¤ÎÌá¤êÃͤΥݥ¤¥ó¥¿·¿¡Ê¸½ºß¤Ï boost::shared_ptr °ìÂò¡Ë
+ template<typename T>
+ struct ptr
+ {
+ typedef shared_ptr<T> type;
+ };
+
+ // ¤³¤Î¥¯¥é¥¹¤«¤é·Ñ¾µ¤¹¤ë¤³¤È¤Ç¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤Ç¤Ï¤Ê¤¯ static ¤Î new_ ´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¤è¤¦¤Ë¤Ê¤ë
+ template<typename Derived >
+ struct enable_static_new_
+ {
+ };
+ // ¾å¤Î¥¯¥é¥¹¤ò·Ñ¾µ¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤òȽÃǤ¹¤ë¥¯¥é¥¹
+ template<typename T>
+ struct enable_if_enabled_static_new_
+ : enable_if< boost::is_base_of< enable_static_new_<T>, T > > {};
+
+
+ // ¥¯¥é¥¹¤Î private ¥á¥ó¥Ð¥¢¥¯¥»¥¹ÍѤΥ¯¥é¥¹¡£
+ // ¥³¥ó¥¹¥È¥é¥¯¥¿¤Ê¤¤¤· new_ ÀÅŪ´Ø¿ô¤ò private ¤Ë¤ª¤¤¤¿¾å¤Ç¡¢
+ // friend class gintenlib::new_core_access;
+ // ¤È¤¹¤ì¤Ð¡¢ new_ ¤ò²ð¤·¤Æ¤·¤«À½ºî¤Ç¤¤Ê¤¤¥¯¥é¥¹¤Ë¤Ê¤ë¡£
+ class new_core_access
+ {
+ // ¤³¤Î¥¯¥é¥¹¤Ï new_ptr ¥Õ¥¡¥ó¥¯¥¿¤Î¤ß¤¬»ÈÍѤǤ¤ë
+ template<typename T, typename>
+ friend class new_ptr;
+
+ // Ä̾ï¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤ò¸Æ¤Ó½Ð¤¹ new
+ template<typename T>
+ static typename ptr<T>::type normal_new()
+ {
+ return typename ptr<T>::type( new T() );
+ }
+ // ¿°ú¿ôÈÇ
+ #define GINTENLIB_GEN( z, n, d ) \
+ template< typename T, BOOST_PP_ENUM_PARAMS( n, typename A ) > \
+ static typename ptr<T>::type normal_new \
+ ( BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) ) \
+ { \
+ return typename ptr<T>::type( new T( BOOST_PP_ENUM_PARAMS( n, arg ) ) ); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
+
+ #undef GINTENLIB_GEN
+
+ // new_ ÀÅŪ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ new
+ template<typename T>
+ static typename ptr<T>::type static_new()
+ {
+ return typename ptr<T>::type( T::new_() );
+ }
+ // ¿°ú¿ôÈÇ
+ #define GINTENLIB_GEN( z, n, d ) \
+ template< typename T, BOOST_PP_ENUM_PARAMS( n, typename A ) > \
+ static typename ptr<T>::type static_new \
+ ( BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) ) \
+ { \
+ return typename ptr<T>::type( T::new_( BOOST_PP_ENUM_PARAMS( n, arg ) ) ); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
+
+ #undef GINTENLIB_GEN
+
+ private:
+ // ¸µ¤«¤é private ¤À¤¬¡¢¶¯Ä´¤¹¤ë°ÕÌ£¤Ç¤Ä¤±¤Æ¤ª¤¯¡£
+ // ¤³¤Î¥¯¥é¥¹¤Ï¹½ÃۤǤ¤Ê¤¤¡£
+ new_core_access();
+
+ };
+
+ // ´Ø¿ô¥ª¥Ö¥¸¥§¥¯¥ÈÈÇ new_¡Ê¥³¥ó¥¹¥È¥é¥¯¥¿ÈÇ¡Ë
+ template<typename T, typename = void>
+ struct new_ptr
+ {
+ typedef typename ptr<T>::type result_type;
+
+ result_type operator()() const
+ {
+ return new_core_access::template normal_new<T>();
+ }
+ // ¿°ú¿ôÈÇ
+ #define GINTENLIB_GEN( z, n, d ) \
+ template< BOOST_PP_ENUM_PARAMS( n, typename A ) > \
+ result_type operator() \
+ ( BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) ) const \
+ { \
+ return new_core_access::template normal_new<T> \
+ ( BOOST_PP_ENUM_PARAMS( n, arg ) ); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
+
+ #undef GINTENLIB_GEN
+ };
+
+ // ´Ø¿ô¥ª¥Ö¥¸¥§¥¯¥ÈÈÇ new_¡ÊÀÅŪ´Ø¿ôÈÇ¡Ë
+ template<typename T>
+ struct new_ptr< T, typename enable_if_enabled_static_new_<T>::type >
+ {
+ typedef typename ptr<T>::type result_type;
+
+ result_type operator()() const
+ {
+ return new_core_access::template static_new<T>();
+ }
+ // ¿°ú¿ôÈÇ
+ #define GINTENLIB_GEN( z, n, d ) \
+ template< BOOST_PP_ENUM_PARAMS( n, typename A ) > \
+ result_type operator() \
+ ( BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) ) const \
+ { \
+ return new_core_access::template static_new<T> \
+ ( BOOST_PP_ENUM_PARAMS( n, arg ) ); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
+
+ #undef GINTENLIB_GEN
+ };
+
+
+ // ËÜÂÎ
+ template<typename T>
+ inline typename ptr<T>::type new_()
+ {
+ return new_ptr<T>()();
+ }
+ // ¿°ú¿ôÈÇ
+ #define GINTENLIB_GEN( z, n, d ) \
+ template< typename T, BOOST_PP_ENUM_PARAMS( n, typename A ) > \
+ inline typename ptr<T>::type new_( BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) ) \
+ { \
+ return new_ptr<T>()( BOOST_PP_ENUM_PARAMS( n, arg ) ); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
+
+ #undef GINTENLIB_GEN
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_NEW__HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_OPTIONS_HPP_
+#define GINTENLIB_INCLUDED_OPTIONS_HPP_
+
+/*
+ <gintenlib/options.hpp>
+
+ options ¡§ getopt Ū¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó²òÀÏ
+
+ ¾Ü¤·¤¯¤Ï <gintenlib/options/options.hpp> ¤ò»²¾È¡£
+
+*/
+
+#include "options/options.hpp"
+
+#endif // #ifndef GINTENLIB_INCLUDED_OPTIONS_HPP_
--- /dev/null
+#ifndef GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
+#define GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
+
+/*
+ <gintenlib/options/exceptions.hpp>
+
+ ¥ª¥×¥·¥ç¥ó²òÀϥ饤¥Ö¥é¥êÍÑÎã³°¥¯¥é¥¹
+
+ Àë¸À¡§
+ // Îã³°´ðËÜ¥¯¥é¥¹
+ struct option_error : std::runtime_error;
+ // ¥ª¥×¥·¥ç¥ó»ØÄêʸ»úÎ󤬤ª¤«¤·¤¤
+ struct invalid_option_string : option_error;
+ // »ØÄꤵ¤ì¤Ê¤¤¥ª¥×¥·¥ç¥ó¤¬ÅϤµ¤ì¤¿
+ struct unknown_option : option_error;
+ // °ú¿ô¤¬É¬ÍפʤΤËÅϤµ¤ì¤Ê¤«¤Ã¤¿
+ struct option_requires_argument : option_error;
+
+ µ¡Ç½¡§
+ Îã³°ÍÑ¥¯¥é¥¹¤Ç¤¹¡£°Ê¾å¡£
+
+*/
+
+#include <stdexcept>
+
+namespace gintenlib
+{
+ // Îã³°´ðËÜ¥¯¥é¥¹
+ struct option_error : std::runtime_error
+ {
+ explicit option_error( const std::string& what_ )
+ : std::runtime_error( what_ ) {}
+ };
+ // ¥ª¥×¥·¥ç¥ó»ØÄêʸ»úÎ󤬤ª¤«¤·¤¤
+ struct invalid_option_string : option_error
+ {
+ explicit invalid_option_string( const std::string& optstr )
+ : option_error( "invalid option format string: " + optstr ) {}
+ };
+ // »ØÄꤵ¤ì¤Ê¤¤¥ª¥×¥·¥ç¥ó¤¬ÅϤµ¤ì¤¿
+ struct unknown_option : option_error
+ {
+ explicit unknown_option( const std::string& opt )
+ : option_error( "unknown option: " + opt ) {}
+ };
+ // °ú¿ô¤¬É¬ÍפʤΤËÅϤµ¤ì¤Ê¤«¤Ã¤¿
+ struct option_requires_argument : option_error
+ {
+ explicit option_requires_argument( const std::string& opt )
+ : option_error( "option requres an argument: " + opt ) {}
+ };
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
--- /dev/null
+#ifndef GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
+#define GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
+
+/*
+ <gintenlib/options/options.hpp>
+
+ options ¡§ getopt Ū¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó²òÀÏ
+
+ Àë¸À¡§
+ struct options
+ {
+ // »ØÄꤵ¤ì¤¿Ê¸»úÎó¤Ç¥ª¥×¥·¥ç¥ó²òÀÏ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë
+ // ʸ»úÎó¤Ï´ðËÜŪ¤Ë getopt ¸ß´¹¡¢ËÁƬ¤Î : ¤È - ¤ÎÆ°ºî¤Î¤ß°ã¤¦
+ explicit options( const std::string& optstr, int argc, char* argv[] );
+
+ // ¼ÂºÝ¤Ë¥ª¥×¥·¥ç¥ó¤ò²òÀϤ¹¤ë
+ typedef int result_type;
+ result_type operator()();
+
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
+ int optind() const;
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀßÄꤹ¤ë
+ void set_optind( int new_index = 1 );
+
+ // °ú¿ô
+ const std::string& optarg() const;
+
+ // ¥¨¥é¡¼»þ¤ËÆɤó¤Ç¤¤¤¿Ê¸»ú
+ int optopt() const;
+
+ }; // struct options
+
+ µ¡Ç½¡§
+ ¥³¥ó¥¹¥È¥é¥¯¥¿¤ÇÍ¿¤¨¤é¤ì¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤ò¸µ¤Ë¡¢¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó¤ò²òÀϤ·¤Þ¤¹¡£
+ ¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï´ðËÜŪ¤Ë£Ç£Î£Õ¤Î getopt ¸ß´¹¤Ç¤¹¤¬¡¢¼ã´³¤Î°ã¤¤¤¬¤¢¤ê¡¢
+ ¤Þ¤ºÌ¤ÃΤΥª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¡¢'?'¤òÊÖ¤µ¤ºÎã³°¤òÅꤲ¤ëÅÀ¡£
+ ¤³¤ì¤Ï ':' ¤ò¥Õ¥©¡¼¥Þ¥Ã¥È¤ÎƬ¤ËÃÖ¤¯¤³¤È¤Ç¡¢Îã³°¤òÅꤲ¤º '?' ¤òÊÖ¤¹¤è¤¦¤ËÊѹ¹¤Ç¤¤Þ¤¹¡£
+ ¤³¤Î¤È¤¡¢°ú¿ô¤¬Â¤ê¤Ê¤¤¾ì¹ç¤Ï ':' ¤òÊÖ¤·¤Þ¤¹¡Ê¤³¤³¤Ï getopt ¤ÎÆ°ºî¤ÈƱ¤¸¡Ë¡£
+ ¤Þ¤¿¥ª¥×¥·¥ç¥óʸ»úÎó¤ÎƬ¤Ë '-' ¤ò»ØÄꤹ¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡Ê£Ç£Î£Õ¤Î»ÅÍͤ¬Îɤ¯Ê¬¤«¤é¤Ê¤«¤Ã¤¿¤Î¤Ç¡Ë¡£
+ ¤Þ¤¿´Ä¶ÊÑ¿ô POSIXLY_CORRECT ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Æ¤âÆ°ºî¤Ï¤Ê¤Ë¤âÊѤï¤ê¤Þ¤»¤ó¡£
+ '+' ¤Ç»Ï¤Þ¤ëʸ»úÎó¤òÅϤ¹¤³¤È¤ÇÂн褷¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¶ñÂÎŪ¤Ê¥Õ¥©¡¼¥Þ¥Ã¥È¤ÎÍ¿¤¨Êý¤Ï°Ê²¼¤ÎÄ̤ꡧ
+ ñÆȤÎʸ»ú¤Ï¡¢°ú¿ô¤ò¼è¤é¤Ê¤¤¥ª¥×¥·¥ç¥ó¤ò¼¨¤¹¡£
+ ʸ»ú¤Î¸å¤Ë ':' ¤¬Â³¤¤¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤Ï°ú¿ô¤ò¼è¤ë¡£
+ ʸ»ú¤Î¸å¤ËÆó¤Ä¤Î ':' ¤¬Â³¤¤¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤Ï°ú¿ô¤ò¼è¤ê¤¦¤ë¡£
+ Î㡧
+ "ab:c::d" ¤ÈÅϤµ¤ì¤¿¤é¡¢a ¤È d ¤Ï°ú¿ô¤Ê¤·¡¢ b ¤Ï°ú¿ô¤¢¤ê¡¢ c ¤Ï°ú¿ô¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¤¤¤¤
+
+ »ÈÍÑÎ㡧
+ // usage: ¥³¥Þ¥ó¥É̾ ¥ª¥×¥·¥ç¥óʸ»úÎó ²òÀϤµ¤»¤¿¤¤°ú¿ô
+ // ¤³¤¦µ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ options ¤Î¤Û¤ÜÁ´µ¡Ç½¤ò¥Æ¥¹¥È¤Ç¤¤ëÎã¤Ç¤¹
+ #include <gintenlib/options.hpp>
+ #include <gintenlib/cast.hpp>
+
+ #include <iostream>
+ using namespace std;
+
+ int main( int argc, char* argv[] )
+ {
+ // °ÅÌÛ¥¥ã¥¹¥È
+ using gintenlib::cast;
+
+ try
+ {
+ if( argc < 2 ){ throw gintenlib::option_error("missing 'OPTSTR'"); }
+
+ // argv[1] ¤ÏÆÃÊ̤ʰú¿ô
+ gintenlib::options opt( argv[1], argc, argv );
+ // ¤Ê¤Î¤Ç²òÀϤµ¤»¤Ê¤¤
+ opt.set_optind( 2 );
+
+ for(;;)
+ {
+ // ²òÀϤµ¤»¤ë¡£ ch ¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤Îʸ»ú¤¬Æþ¤ë
+ int ch = opt();
+ if( ch == -1 ){ break; } // -1: ²òÀϽª¤ï¤ê
+
+ switch(ch)
+ {
+ case '?':
+ // ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "unknown option '" << cast<char>( opt.optopt() ) << "' is given. continue...\n";
+ break;
+
+ case ':':
+ // Ʊ¤¸¤¯ ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "option '" << cast<char>( opt.optopt() ) << "'requires argument. continue...\n";
+ break;
+
+ default:
+ // ¥ª¥×¥·¥ç¥ó°ìÈÌ
+ cout << "option '" << cast<char>( ch ) << "' is given.\n";
+
+ // °ú¿ô¤Ï optarg() ¤Ç³ÍÆÀ
+ // °ú¿ô¤¬Ìµ¤¤¾ì¹ç¤Ï string() ¤¬Æþ¤ë
+ if( !opt.optarg().empty() )
+ {
+ cout << " argument: " << opt.optarg() << endl;
+ }
+ break;
+
+ }
+ }
+
+ // ²òÀϽªÎ»¡£Í¾¤Ã¤¿¥ª¥×¥·¥ç¥ó¤Ï argv[opt.optind()] ¡Á argv[argc-1] ¤Ë½¸¤á¤é¤ì¤ë
+ // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó°ú¿ô¤¬È󥪥ץ·¥ç¥ó°ú¿ô¤Î¸å¤Ë¤¢¤ë¾ì¹ç¡¢ argv ¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤ë
+ // ¤³¤ÎÆ°ºî¤òÈò¤±¤¿¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤Î°ú¿ô¤ò '+' ¤Ç»Ï¤á¤ì¤Ð¤è¤¤
+ cout << "\nextra options are:\n";
+ for( int i = opt.optind(); i < argc; ++i )
+ {
+ cout << argv[i] << endl;
+ }
+ }
+ catch( gintenlib::option_error& e )
+ {
+ // ¥ª¥×¥·¥ç¥ó²òÀϤ˼ºÇÔ¤·¤ÆÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ï¤³¤Á¤é¤ËÈô¤Ö
+ cerr << e.what() << endl;
+ cerr << "usage: " << argv[0] << " OPTSTR [OPTIONS]\n";
+
+ return 1;
+ }
+ catch( std::exception& e )
+ {
+ // ¤½¤Î¤Û¤«¤ÎÎã³°
+ cerr << e.what() << endl;
+ return 1;
+ }
+ } // main( argc, argv )
+
+
+ Ê䡧
+ ¡¦¼ç¤Ë <unistd.h> ¤¬¥¤¥ó¥¯¥ë¡¼¥É¤Ç¤¤Ê¤¤½èÍý·Ï¸þ¤±¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+ ¡¦¤¢¤È¡¢¤â¤í¤â¤í¤Î»ö¾ð¤Ç <unistd.h> ¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¤¯¤Ê¤¤¾ì¹ç¤È¤«¤Ë¤â¡£
+ ¡¦¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤ò»È¤ï¤Ê¤¤¡¢¼ºÇÔ»þ¤ÏÎã³°¤òÅꤲ¤Æ¤¯¤ì¤ë¡¢¤È¤¤¤¦¤Î¤â¥á¥ê¥Ã¥È¤Ç¤¹¡£
+ ¡¦¾åµ¤Î¤è¤¦¤ÊÍýͳ¤¬Ìµ¤¤¤Ê¤é¡¢ÁÇľ¤Ë getopt ¤ò»È¤Ã¤¿¤Û¤¦¤¬¤è¤¤¤È»×¤¤¤Þ¤¹¡£
+ ¡¦ÂåÂؼêÃʤȤ·¤Æ¤Ï boost ¤Î progtam_options ¤Ã¤Æ¤Î¤â¤¢¤ë¤±¤É¡¢¥ê¥ó¥¯¤·¤Ê¤¤ã¤¤¤±¤Ê¤¤¤Î¤¬ÌÌÅÝ¡£
+ ¡¦¤¢¤È¡¢¤¤¤í¤¤¤í¥ª¡¼¥Ð¡¼¥¹¥Ú¥Ã¥¯²á¤®¤ëµ¤¤¬¤·¤Æµ¤·Ú¤Ë¤Ï»È¤¤¤Ë¤¯¤¤¤Ç¤¹¡£¸Ä¿ÍŪ¤Ë¡£
+ ¡¦¤Þ¡¼Â礷¤¿½èÍý¤ò¤·¤Ê¤¤¤Ê¤é¡¢¤³¤ì¤ò»È¤Ã¤È¤±¡£¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É¤Î¤ß¤ÇºÑ¤à¤·¤Í¡£
+ ¡¦¥Æ¥ó¥×¥ì¡¼¥È¡© ¤Ê¤Ë¤½¤ìÈþÌ£¤·¤¤¤Î¡©
+
+*/
+
+#include "exceptions.hpp"
+
+#include <map>
+#include <string>
+#include <cassert>
+#include <algorithm>
+#include "../tribool.hpp"
+#include "../to_string.hpp"
+#include "../cast.hpp"
+
+namespace gintenlib
+{
+ // ¥ª¥×¥·¥ç¥ó²òÀϵ¡
+ struct options
+ {
+ // optstr ¤Ç¼¨¤µ¤ì¤ë¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó¤ò²òÀϤ¹¤ë
+ explicit options( const std::string& optstr, int argc_, char* argv_[] )
+ : argc(argc_), argv(argv_), index(1), index_max(argc), next_char(0), opt('?'),
+ posixly_correct(false), throws_on_error(true)
+ {
+ using namespace std;
+ char prev = 0;
+
+ for( string::const_iterator ite = optstr.begin(), end = optstr.end();
+ ite != end; ++ite )
+ {
+ char ch = *ite;
+
+ if( ch == ':' )
+ {
+ // ¥³¥í¥óµ¹æ¤ÏľÁ°¤Ë²òÀϤ·¤¿Ê¸»ú¤Ë¤è¤Ã¤ÆÆ°ºî¤òÀÚ¤êÂؤ¨¤ë
+ if( prev == 0 )
+ {
+ // ʸƬ¤Î¥³¥í¥ó¤Ï¡ÖÎã³°¤òÅꤲ¤Ê¤¤¡×»ØÄê¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë
+ throws_on_error = false;
+ }
+ else
+ {
+ // ľÁ°¤Îʸ»ú¤ò¸¡º÷¤¹¤ë
+ map_type::iterator pos = m.find( prev );
+ // ¸«¤Ä¤«¤é¤Ê¤¤¤³¤È¤ÏͤêÆÀ¤Ê¤¤
+ assert( pos != m.end() );
+
+ tribool& has_arg = (*pos).second;
+ if( !has_arg )
+ {
+ // °ì²óÌܤΠ: ¤Î»þ¤Ï¡¢°ú¿ôɬ¿Ü
+ has_arg = true;
+ }
+ else
+ {
+ // Æó²óÌܰʹߤϡ¢°ú¿ôǤ°Õ
+ has_arg = indeterminate;
+ }
+ }
+ }
+ else if( ch == '+' )
+ {
+ if( prev != 0 )
+ {
+ // + »ØÄê¤ÏËÁƬ¤Ë¤Î¤ßÃÖ¤±¤ë
+ throw invalid_option_string( optstr );
+ }
+ // ¤³¤Î»ØÄ꤬¤¢¤Ã¤¿¾ì¹ç¡¢°ú¿ô¤Î½çÈÖ¤ÏÆþ¤ìÂؤ¨¤Ê¤¤
+ posixly_correct = true;
+ }
+ else if( ch == '-' )
+ {
+ // - µ¹æ¤ÏGNU³ÈÄ¥¤Ë¸ºß¤¹¤ë¤¬¡¢¤è¤¯Ê¬¤«¤é¤Ê¤¤¤Î¤Ç¾ï¤ËÉÔÀµ¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë¡ÊÍ×½¤Àµ¡Ë
+ throw invalid_option_string( optstr );
+ }
+ else if( ch == '?' )
+ {
+ // ? µ¹æ¤Ï¥ª¥×¥·¥ç¥óʸ»ú¤È¤·¤Æ¤Ï»È¤¨¤Ê¤¤¤Î¤ÇÉÔÀµ
+ throw invalid_option_string( optstr );
+ }
+ else
+ {
+ // ¾°ìÈÌ
+ // ':' '+' '-' '\0' °Ê³°¤Ê¤é¤É¤ó¤Êʸ»ú¤Ç¤â¤¤¤¤
+ if( m.count( ch ) != 0 )
+ {
+ // Ʊ¤¸¥ª¥×¥·¥ç¥óʸ»ú¤òÆó²óÄêµÁ¤·¤Á¤ã¥À¥á
+ throw invalid_option_string( optstr );
+ }
+ // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï°ú¿ô¤Ê¤·
+ m[ch] = false;
+ // : »ØÄꤵ¤ì¤¿¤È¤¤Î¤¿¤á¤Ë¡¢Ê¸»ú¤òÊݸ¤¹¤ë
+ prev = ch;
+ }
+
+ } // for
+ } // constructor
+
+ // ¼ÂºÝ¤Î²òÀϤϤ³¤Á¤é¤Ç
+ typedef int result_type;
+ result_type operator()()
+ {
+ using namespace std; // for assert
+
+ // ¤Þ¤º¥¤¥ó¥Ç¥Ã¥¯¥¹¤Î¥Á¥§¥Ã¥¯
+ if( index_max <= index ){ return -1; }
+ // °ú¿ôʸ»úÎó¤Î½é´ü²½
+ arg = string();
+
+ // ¼¡¤Ë½èÍý¤¹¤ëʸ»ú¤¬»ØÄꤵ¤ì¤Æ̵¤¤¾ì¹ç¡ÊÉáÄ̤Ϥ½¤¦¡Ë¤Ï
+ // argv[index] ¤Ë¿Ê¤à
+ if( !next_char )
+ {
+ next_char = argv[index];
+ assert( next_char != 0 );
+
+ // ¥ª¥×¥·¥ç¥óʸ»úÎó¤À¤«¤é¡¢'-' ¤Ç¤Ï¤¸¤Þ¤ë¤Ï¤º
+ char ch = *next_char;
+ if( ch == '-' )
+ {
+ // OK¡£¤½¤Î¼¡¤Ë¶½Ì£¤¬¤¢¤ë
+ ++next_char;
+ }
+ else
+ {
+ // ¥ª¥×¥·¥ç¥óʸ»úÎó¤Ç¤Ï¤Ê¤«¤Ã¤¿
+
+ // ¤È¤ê¤¢¤¨¤º¥Ý¥¤¥ó¥¿¤Ï¥ê¥»¥Ã¥È
+ next_char = 0;
+
+ if( posixly_correct )
+ {
+ // POSIX Ū¤Ë¤Ï¡¢°ì²ó¼ºÇÔ¤¹¤ë¤È¤½¤ì¤Ç½ª¤ï¤ê
+ return -1;
+ }
+ else
+ {
+ // GNU ³ÈÄ¥¤À¤È¡¢°ú¿ô¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤Æ¥Þ¥Ã¥Á¥ó¥°¤ò³¤±¤ë
+ for( int i = index + 1; i < index_max; ++i )
+ {
+ char* p = argv[i];
+ if( *p == '-' )
+ {
+ rotate( &argv[index], &argv[i], &argv[argc] );
+ index_max -= i - index;
+ return (*this)();
+ }
+ }
+
+ // ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿
+ // ʤӽç¤òÉü¸µ¤¹¤ë
+ rotate( &argv[index], &argv[index_max], &argv[argc] );
+ index_max = index;
+
+ return -1;
+ }
+ }
+ }
+
+ // ¤³¤Î»þÅÀ¤Ç¡¢next_char ¤Ï¥ª¥×¥·¥ç¥óʸ»ú¤ò»Ø¤·¤Æ¤¤¤ëȦ
+ char ch = *next_char;
+
+ if( ch == 0 )
+ {
+ // - ¤Î¤ß¤Î°ú¿ô¤¬ÅϤµ¤ì¤¿
+ // ¤³¤ì¤ÏÈ󥪥ץ·¥ç¥óʸ»úÎó¤È¤·¤Æ°·¤¦
+ next_char = 0;
+ return -1;
+ }
+ else if( ch == '-' )
+ {
+ // '--' ¤ÏŤ¤¥ª¥×¥·¥ç¥ó¤«¡¢¥ª¥×¥·¥ç¥ó¤Î½ªÎ»¤òɽ¤¹
+ ++next_char;
+ if( *next_char != 0 )
+ {
+ // Ť¤¥ª¥×¥·¥ç¥ó¤Ë¤ÏÈóÂбþ
+ throw unknown_option( "--" + to_str(next_char) );
+ }
+
+ // Ť¤¥ª¥×¥·¥ç¥ó¤Ç¤Ï¤Ê¤¤¤Î¤Ç¥ª¥×¥·¥ç¥ó¤Î½ªÎ»¤òɽ¤¹
+ // ½ªÎ»½èÍý¤ò¤·¤Æ
+ terminate_analysis_();
+ // ¤ª¤·¤Þ¤¤
+ return -1;
+ }
+
+ // ch ¤ò¥Þ¥Ã¥×¤«¤é¸¡º÷¤¹¤ë
+ map_type::const_iterator ite = m.find( ch );
+ if( ite == m.end() )
+ {
+ // ¸ºß¤·¤Ê¤¤¤è¤¦¤Ê¤é¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤ò optopt ¤Ë³ÊǼ¤·
+ opt = ch;
+ // °ì±þ¡¢Ê¸»ú¤ò¼¡¤Ë¿Ê¤á¤Æ
+ advance_next_char_();
+
+ // Îã³°¤òÅꤲ¤ë
+ if( throws_on_error )
+ {
+ throw unknown_option( "-" + to_str( cast<char>(ch) ) );
+ }
+
+ // Åꤲ¤Ê¤¤¾ì¹ç¤Ï '?' ¤òÊÖ¤¹
+ return '?';
+ }
+
+ // °ú¿ô¤Ï¤¢¤ë¡©
+ tribool has_arg = (*ite).second;
+ if( !has_arg )
+ {
+ // °ú¿ô¤Î¤Ê¤¤¾ì¹ç
+ // ¤È¤ê¤¢¤¨¤º¼¡¤Îʸ»ú¤Ë¿Ê¤á¤ë
+ advance_next_char_();
+
+ // ¤½¤Îʸ»ú¤òÊÖ¤¹
+ return ch;
+ }
+
+ // ¤³¤Î»þÅÀ¤Ç¡¢°ú¿ô¤Ï¡Ö¤¢¤ë¡×¤«¡ÖǤ°Õ¡×¤«¤Î¤É¤Á¤é¤«
+ ++next_char;
+ if( *next_char != 0 )
+ {
+ // ³¤¤¬¤¢¤ë¤Ê¤é¡¢¤½¤¤¤Ä¤¬°ú¿ôʸ»úÎó
+ arg = string( next_char );
+
+ advance_index_();
+ return ch;
+ }
+
+ // °ú¿ôɬ¿Ü¤«Èݤ«
+ if( has_arg )
+ {
+ // ɬ¿Ü¤Ê¤é¡¢¼¡¤Î argv ¤ò°ú¿ô¤È¤ß¤Ê¤¹
+ advance_index_();
+
+ if( index_max <= index )
+ {
+ return missing_argument_found_( ch );
+ }
+
+ // ¼¡¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¡¢¤Þ¤ë¤Þ¤ë°ú¿ô¤È¸«¤Ê¤¹
+ arg = argv[index];
+ // ¤¿¤À¤· argv[index] ¤¬ "--" ¤Î¤È¤¤ÏÎã³°
+ if( arg == "--" )
+ {
+ arg = string();
+ terminate_analysis_();
+ return missing_argument_found_( ch );
+ }
+
+ // ¤µ¤é¤Ë²òÀϹԤò¿Ê¤á¤ë
+ advance_index_();
+ return ch;
+ }
+ else
+ {
+ // °ú¿ô¤¬¾Êά²Äǽ¤Ç¡¢¥ª¥×¥·¥ç¥óʸ»ú¤ÈƱ»þ¤Ë°ú¿ô¤¬ÅϤµ¤ì¤Æ¤¤¤Ê¤¤¤Ê¤é
+ // °ú¿ô¤ò¶õʸ»úÎó¤Ë¤·¤Æ ch ¤òÊÖ¤¹
+ advance_index_();
+ return ch;
+ }
+
+ assert( !"should not get here." );
+ return '?';
+ }
+
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
+ int optind() const { return index; }
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀßÄꤹ¤ë
+ void set_optind( int new_index = 1 )
+ {
+ if( new_index < 1 ){ new_index = 1; }
+
+ index = new_index; next_char = 0; index_max = argc;
+ arg = std::string(); opt = '?';
+ }
+
+ // °ú¿ô
+ const std::string& optarg() const { return arg; }
+
+ // ¥¨¥é¡¼»þ¤ËÆɤó¤Ç¤¤¤¿Ê¸»ú
+ int optopt() const { return opt; }
+
+ private:
+ typedef std::map< char, tribool > map_type;
+ map_type m;
+ int argc;
+ char** argv;
+ int index, index_max;
+ const char* next_char;
+ std::string arg;
+ int opt;
+ bool posixly_correct, throws_on_error;
+
+ // ÆâÉô´Ø¿ô
+ // ²òÀϤ¹¤ë¹Ô¤ò°ì¤Ä¿Ê¤á¤ë
+ void advance_index_()
+ {
+ ++index;
+ next_char = 0;
+ }
+ // ʸ»ú¤ò°ìʸ»ú¿Ê¤á¤ë
+ void advance_next_char_()
+ {
+ // ¤È¤ê¤¢¤¨¤º¼¡¤Îʸ»ú¤Ë¿Ê¤á¤ë
+ ++next_char;
+
+ if( *next_char == 0 )
+ {
+ // ¼¡¤Îʸ»ú¤¬Â¸ºß¤·¤Ê¤¤¤Ê¤é¡¢²òÀϤΥ¤¥ó¥Ç¥Ã¥¯¥¹¤ò¿Ê¤á¤ë
+ ++index;
+ next_char = 0;
+ }
+ }
+ // °ú¿ô¤¬Â¤ê¤Ê¤¤
+ int missing_argument_found_( int ch )
+ {
+ // °ú¿ôÉÔÂ
+ opt = ch;
+
+ // Îã³°¤òÅꤲ¤ë
+ if( throws_on_error )
+ {
+ throw option_requires_argument( "-" + to_str( cast<char>(ch) ) );
+ }
+
+ return ':';
+ }
+ // '--' ¤ËÁø¶ø¤·¤¿
+ void terminate_analysis_()
+ {
+ // ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò¿Ê¤á¤Æ
+ advance_index_();
+
+ // ʤÓÂؤ¨¤ÎÅÓÃæ¤Ê¤éʤӽç¤òÉü¸µ¤¹¤ë
+ if( argc != index_max )
+ {
+ std::rotate( &argv[index], &argv[index_max], &argv[argc] );
+ }
+
+ // ¤³¤ì°Ê¾å¤Ï²òÀϤ·¤Ê¤¤¤è
+ index_max = index - 1;
+ }
+
+ }; // struct options
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
+#define GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
+
+/*
+
+ <gintenlib/plane/angle.hpp>
+
+ angle ¡§ Ê¿Ì̳Ñ
+
+ µ¡Ç½¡§
+ Ê¿Ì̳Ѥò°·¤¦¥¯¥é¥¹¡£
+ £Ã¡Ü¡Ü¤Ë¤ª¤¤¤Æ³ÑÅÙ¤Ï radian ¤Ç°·¤¤¤Þ¤¹¤¬¡¢¤¿¤Þ¤Ë degree ¤â»È¤¤¤¿¤¯¤Ê¤ë¤Ç¤·¤ç¤¦¡£
+ ¤½¤¦¤¤¤¦¤È¤¤Ë¡¢Æó¤Ä¤Îɽ¤·Êý¤òº®Æ±¤·¤Ê¤¤¤è¤¦¤Ë°·¤¨¤ë¥¯¥é¥¹¤Ç¤¹¡£
+ ¤¢¡¢¤½¤ì¤«¤é³ÑÅÙ¤ÎÀµµ¬²½¡Ê-¦Ð¤«¤é¦Ð¤Î´Ö¤Ë¤Ê¤ë¤è¤¦Ä´À᤹¤ë¡Ë¤â¤Ç¤¤Þ¤¹¡£¤Ä¤¤¤Ç¤Ë¡£
+
+ ¼ç¤ËÃÆËë¤òºî¤ë¤È¤¤Ë»È¤¦ÄøÅ٤Υ¯¥é¥¹¤Ç¤¹¡£
+
+ »ÈÍÑÎ㡧
+ angle x, y = degree(60); // x ¤Ï 0, y ¤Ï 60¡ë
+ // »°³Ñ´Ø¿ô
+ cout << sin(x) << ", " << sin(y) << endl;
+ // µÕ»°³Ñ´Ø¿ô
+ angle z = angle::asin(0.5);
+ // ¿ôÃͤËÊÑ´¹
+ cout << "z ¤Ï " << to_rad(z) << " ¥é¥¸¥¢¥ó¡¢ " << to_deg(z) << " Å٤Ǥ¹¡£";
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+
+#include "../math.hpp" // for M_PI
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // angle : Ê¿Ì̳Ñ
+ template<typename Real>
+ struct basic_angle
+ : private boost::totally_ordered< basic_angle<Real> >,
+ private boost::additive< basic_angle<Real> >,
+ private boost::multiplicative< basic_angle<Real>, Real >,
+ private boost::modable< basic_angle<Real> >
+ {
+ typedef Real real_type;
+ real_type theta;
+
+ basic_angle()
+ : theta() {}
+
+ template<typename T>
+ basic_angle( const basic_angle<T>& src )
+ : theta( src.theta ) {}
+
+ // ¼Â¿ôÃͤ«¤éÀ¸À®¡¢Ã±°Ì¤Ï rad
+ explicit basic_angle( real_type theta_ )
+ : theta(theta_) {}
+
+ // theta ¤ÎÃͤòÆÀ¤ë
+ real_type to_deg() const
+ {
+ return theta * 180 / M_PI;
+ }
+ friend real_type to_deg( const basic_angle& target )
+ {
+ return target.to_deg();
+ }
+ friend real_type deg( const basic_angle& target )
+ {
+ return target.to_deg();
+ }
+ real_type to_rad() const
+ {
+ return theta;
+ }
+ friend real_type to_rad( const basic_angle& target )
+ {
+ return target.to_rad();
+ }
+ friend real_type rad( const basic_angle& target )
+ {
+ return target.to_rad();
+ }
+
+ // operator overloads
+ // Èæ³Ó
+ friend bool operator==( const basic_angle& lhs, const basic_angle& rhs )
+ {
+ return lhs.theta == rhs.theta;
+ }
+ friend bool operator<( const basic_angle& lhs, const basic_angle& rhs )
+ {
+ return lhs.theta < rhs.theta;
+ }
+ // ²Ã¸º»»
+ basic_angle& operator+=( const basic_angle& rhs )
+ {
+ theta += rhs.theta;
+ return *this;
+ }
+ basic_angle& operator-=( const basic_angle& rhs )
+ {
+ theta -= rhs.theta;
+ return *this;
+ }
+ // Éä¹æȿž
+ basic_angle operator-() const
+ {
+ return basic_angle( -theta );
+ }
+ // ³Ý¤±»»¡¢³ä¤ê»»
+ basic_angle& operator*=( const real_type& rhs )
+ {
+ theta *= rhs;
+ return *this;
+ }
+ basic_angle& operator/=( const real_type& rhs )
+ {
+ theta /= rhs;
+ return *this;
+ }
+ // Èæ¤Î»»½Ð
+ real_type operator/( const basic_angle& rhs ) const
+ {
+ return theta / rhs.theta;
+ }
+ // ¾ê;±é»»
+ // std::fmod ¤ò¸Æ¤Ó½Ð¤¹¤À¤±
+ basic_angle& operator%=( const basic_angle& rhs )
+ {
+ using std::fmod;
+
+ theta = fmod( theta, rhs.theta );
+
+ return *this;
+ }
+ // ¥Ù¥¯¥È¥ë¤ËÂФ·¤Æ³Ý¤±»»¤¹¤ë¤È²óžÁàºî
+ // ¤¿¤À¤·¡¢º¸¤«¤é³Ý¤±¤¿»þ¤Î¤ß
+ basic_vector<Real> operator*( const basic_vector<Real>& target ) const
+ {
+ return rotate( target, *this );
+ }
+
+ // [ -¦Ð, ¦Ð ] ¤ÎÈϰϤËÊäÀµ
+ basic_angle& normalize()
+ {
+ using std::fmod;
+
+ if( theta > M_PI )
+ {
+ // ¦Ð¤À¤±¤º¤é¤·¤Æ¸µ¤ËÌ᤹
+ theta = fmod( theta + M_PI, M_PI * 2 ) - M_PI;
+ }
+ else if( theta < -M_PI )
+ {
+ // ¤Á¤ç¤Ã¤È¤ä¤ä¤³¤·¤¤¤±¤Éʬ¤«¤ë¤Ï¤º¡Ê¤¿¤Ö¤ó¡Ë
+ theta = -fmod( -theta + M_PI, M_PI * 2 ) + M_PI;
+ }
+
+ // °ì±þ³Î¤«¤á¤Æ¤ª¤¯¤è¡©
+ assert( -M_PI <= theta && theta <= M_PI );
+
+ return *this;
+ }
+ friend basic_angle normalized( const basic_angle& target )
+ {
+ basic_angle temp = target;
+ return temp.normalize();
+ }
+ // [ 0, 2¦Ð ) ¤ÎÈϰϤËÊäÀµ
+ basic_angle& unique()
+ {
+ using std::fmod;
+
+ if( theta >= M_PI * 2 )
+ {
+ theta = fmod( theta, M_PI * 2 );
+ }
+ else if( theta < 0 )
+ {
+ theta = M_PI * 2 - fmod( -theta, M_PI * 2 );
+ }
+
+ // °ì±þ³Î¤«¤á¤Æ¤ª¤¯¤è¡©
+ assert( 0 <= theta && theta < M_PI * 2 );
+
+ return *this;
+ }
+ friend basic_angle uniqued( const basic_angle& target )
+ {
+ basic_angle temp = target;
+ return temp.unique();
+ }
+
+ // »°³Ñ´Ø¿ô
+ #define GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( func ) \
+ real_type func() const \
+ { \
+ using std::func; \
+ return func( theta ); \
+ } \
+ friend real_type func( const basic_angle& x ) \
+ { \
+ return x.func(); \
+ }
+
+ // ¼ÂºÝ¤ËÀ¸À®
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( sin )
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( cos )
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( tan )
+
+ #undef GINTENLIB_PLANE_ANGLE_GEN_FUNCTION
+
+ // µÕ»°³Ñ´Ø¿ô
+ static basic_angle asin( real_type x )
+ {
+ using std::asin;
+ return basic_angle( asin(x) );
+ }
+ static basic_angle acos( real_type x )
+ {
+ using std::acos;
+ return basic_angle( acos(x) );
+ }
+ static basic_angle atan( real_type x )
+ {
+ using std::atan;
+ return basic_angle( atan(x) );
+ }
+ static basic_angle atan2( real_type y, real_type x )
+ {
+ using std::atan2;
+ return basic_angle( atan2( y, x ) );
+ }
+
+ };
+ typedef basic_angle<double> angle;
+
+ // ¥é¥¸¥¢¥ó <--> ÅÙ ´¹»»
+ template<typename Real>
+ Real degree( const basic_angle<Real>& x )
+ {
+ return x.to_deg();
+ }
+ template<typename Real>
+ basic_angle<Real> degree( Real deg )
+ {
+ return basic_angle<Real>( deg * M_PI / 180 );
+ }
+ template<typename Real>
+ Real radian( const basic_angle<Real>& x )
+ {
+ return x.to_rad();
+ }
+ template<typename Real>
+ basic_angle<Real> radian( Real rad )
+ {
+ return basic_angle<Real>( rad );
+ }
+ // û½Ì̾
+ template<typename Real>
+ basic_angle<Real> deg( Real deg_ )
+ {
+ return degree( deg_ );
+ }
+ template<typename Real>
+ basic_angle<Real> rad( Real rad_ )
+ {
+ return radian( rad_ );
+ }
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_FWD_HPP_
+#define GINTENLIB_PLANE_INCLUDED_FWD_HPP_
+
+/*
+
+ <gintenlib/plane/fwd.hpp>
+
+ ¤¤¤í¤¤¤í¤ÈÀè¹ÔÀë¸À¤¹¤ë¥Ø¥Ã¥À¤Ç¤¹¡£
+
+*/
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ template< typename T >
+ struct basic_angle;
+
+ template< typename T >
+ struct basic_vector;
+
+ template< typename T >
+ struct basic_point;
+
+ template< typename T >
+ struct basic_rect;
+
+ template< typename T >
+ struct basic_quadrangle;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_FWD_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_POINT_HPP_
+#define GINTENLIB_PLANE_INCLUDED_POINT_HPP_
+
+/*
+
+ <gintenlib/plane/point.hpp>
+
+ point ¡§ Æ󼡸µ°ÌÃÖ¥Ù¥¯¥È¥ë
+
+ µ¡Ç½¡§
+ Æ󼡸µ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤òɽ¤¹¥¯¥é¥¹¡£
+ °ÌÃÖ¥Ù¥¯¥È¥ë¤Ê¤Î¤Ç²Ã»»¤Ç¤¤Þ¤»¤ó¡£¼Â¿ôÇܤâ½ÐÍè¤Þ¤»¤ó¡£
+ ¤Ç¤âÁêÂÐ¥Ù¥¯¥È¥ë¡Êvector¡Ë¤ò²Ã»»¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤¹¡£
+ ¤Á¤Ê¤ß¤Ëº¹¤ò¼è¤ë¤³¤È¤Ï²Äǽ¤Ç¡¢¤½¤¦¤¹¤ë¤ÈÁêÂÐ¥Ù¥¯¥È¥ë¤ËÊѲ½¤·¤Þ¤¹¡£
+ °ÌÃÖ¥Ù¥¯¥È¥ë¤ÈÁêÂÐ¥Ù¥¯¥È¥ë¤òº®Æ±¤¹¤ë¤È¥Ð¥°¤Î¸µ¤Ë¤Ê¤ë¤Î¤Ç¡¢¤½¤ì¤òËɤ°¤¿¤á¤À¤±¤Î¥¯¥é¥¹¡£
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // point : °ÌÃÖ¥Ù¥¯¥È¥ë
+ template<typename Real>
+ struct basic_point : private boost::additive< basic_point<Real>, basic_vector<Real> >
+ , private boost::equality_comparable< basic_point<Real> >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_point()
+ : x(), y() {}
+
+ basic_point( real_type x_, real_type y_ )
+ : x(x_), y(y_) {}
+
+ template<typename T>
+ basic_point( const basic_point<T>& src )
+ : x(src.x), y(src.y) {}
+
+ template<typename T>
+ explicit basic_point( const basic_vector<T>& src )
+ : x(src.first), y(src.second) {}
+
+ // operator overloads
+ basic_point<Real> operator+=( const basic_vector<Real>& rhs )
+ {
+ x += rhs.x; y += rhs.y;
+ return *this;
+ }
+ basic_point<Real> operator-=( const basic_vector<Real>& rhs )
+ {
+ x -= rhs.x; y -= rhs.y;
+ return *this;
+ }
+ // ¸å¡¢°ÌÃÖ¥Ù¥¯¥È¥ëƱ»Î¤Îº¹Ê¬
+ basic_vector<Real> operator-( const basic_point& rhs ) const
+ {
+ return basic_vector<Real>( x - rhs.x, y - rhs.y );
+ }
+ // ÅùÃÍÈæ³Ó
+ bool operator==( const basic_point& rhs ) const
+ {
+ return ( x == rhs.x ) && ( y == rhs.y );
+ }
+
+ // vector ¤ËÊÑ´¹
+ basic_vector<Real> to_vector() const
+ {
+ return basic_vector<Real>( x, y );
+ }
+
+ };
+ typedef basic_point<double> point;
+
+ // ÃæÅÀ¤òµá¤á¤ë
+ template<typename T>
+ basic_point<T> midpoint( const basic_point<T>& p1, const basic_point<T>& p2 )
+ {
+ return basic_point<T>( (p1.x+p2.x)/2, (p1.y+p2.y)/2 );
+ }
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_POINT_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
+#define GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
+
+/*
+
+ <gintenlib/plane/quadrangle.hpp>
+
+ quadrangle ¡§ Æ󼡸µ¶õ´Ö¾å¤Î»Í³Ñ·Á
+
+ Àë¸À¡§
+ // quadrangle : »Í³Ñ·Á
+ template<typename Real>
+ struct basic_quadrangle
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ // Ãæ¿´ºÂɸ
+ pos_type pos;
+ // ³ÆĺÅÀ¤ÎÃæ¿´ºÂɸ¤«¤é¤Î°ÌÃÖ¥Ù¥¯¥È¥ë
+ vec_type a1, a2, a3, a4;
+
+ basic_quadrangle();
+
+ // ¸¶ÅÀ¤òÃæ¿´¤È¤·¤¿»Í³Ñ·Á¤òÀ½ºî¤¹¤ë
+ basic_quadrangle( const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ );
+
+ // °ÌÃÖ¥Ù¥¯¥È¥ë£´¤Ä¤«¤é»Í³Ñ·Á¤òÀ½ºî¤¹¤ë¡£
+ // Ãæ¿´¤Ï£´ÅÀ¤ÎÊ¿¶Ñ¡¢¤¹¤Ê¤ï¤Á½Å¿´
+ basic_quadrangle( const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ );
+
+ // Á´Í×ÁǤò»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ );
+
+ // Á´Í×ÁǤò°ÌÃÖ¥Ù¥¯¥È¥ë¤Ç»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ );
+
+ template<typename T>
+ basic_quadrangle( const basic_quadrangle<T>& src );
+
+
+ // ³ÆĺÅÀ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤ò»»½Ð
+ pos_type vertex1() const { return pos + a1; }
+ pos_type vertex2() const { return pos + a2; }
+ pos_type vertex3() const { return pos + a3; }
+ pos_type vertex4() const { return pos + a4; }
+
+ // operator[]
+ // ¥¤¥ó¥Æ¥Ã¥¯¥¹¤ËÂбþ¤¹¤ëĺÅÀºÂɸ¤ò»»½Ð
+ pos_type operator[]( std::size_t index ) const;
+ pos_type at( std::size_t index ) const;
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ // ¥á¥ó¥ÐÈǤϼ«¿È¤òÊѹ¹¡¢ friend ÈǤϷë²Ì¤ò½ÐÎÏ¡£
+ basic_quadrangle& shift( const vec_type& d );
+ friend basic_quadrangle shift( const basic_quadrangle& target, const vec_type& d );
+
+ // ĺÅÀ¤Î°ÌÃÖ¤òÊѤ¨¤º¡¢Ãæ¿´¤òÊѹ¹
+ // friend ÈǤϤ¢¤ê¤Þ¤»¤ó¡£
+ basic_quadrangle& move_center( const pos_type& center );
+ basic_quadrangle& move_center( const vec_type& d );
+ // °ú¿ô¤Ê¤·¤À¤È½Å¿´¤Ë»ý¤Ã¤Æ¤¤¤¯
+ basic_quadrangle& move_center();
+
+ // ²óž
+ // rect, vector ¤È¤«¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¡£
+ // Ãæ¿´ºÂɸ¤ò¤ï¤¶¤ï¤¶¸ÄÊ̤ËÀßÄꤷ¤Æ¤¤¤ë¤Î¤Ï¡¢¤³¤Î¤È¤¤Î²óž¼´¤ò·è¤á¤ë¤¿¤á¡£
+ template<typename Angle>
+ basic_quadrangle& rotate( const Angle& theta );
+ basic_quadrangle& rotate( real_type s, real_type c );
+ template<typename Angle>
+ friend basic_quadrangle rotate( const basic_quadrangle& x, const Angle& theta );
+ friend basic_quadrangle rotate( const basic_quadrangle& x, real_type s, real_type c );
+
+ };
+ typedef basic_quadrangle<double> quadrangle;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¶õ´Ö¾å¤Î¡¢ÄºÅÀ¤Î°ÌÃÖ¤ÈÃæ¿´¤Î³ÎÄꤷ¤¿¤ò»Í³Ñ·Á¤òɽ¤¹¥¯¥é¥¹¡£
+ Ê¿¹Ô°ÜÆ°¡¢²óž¤Ê¤É¤¬¹Ô¤¨¤Þ¤¹¡£¤Ä¡¼¤«Ì¾Á°Ä¹¤¤¤è¡£
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+#include "point.hpp"
+
+namespace gintenlib
+{
+ namespace plane
+ {
+
+ // quadrangle : »Í³Ñ·Á
+ template<typename Real>
+ struct basic_quadrangle
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ // Ãæ¿´ºÂɸ
+ pos_type pos;
+ // ³ÆĺÅÀ¤ÎÃæ¿´ºÂɸ¤«¤é¤Î°ÌÃÖ¥Ù¥¯¥È¥ë
+ vec_type a1, a2, a3, a4;
+
+ basic_quadrangle()
+ : pos(), a1(), a2(), a3(), a4() {}
+
+ // ¸¶ÅÀ¤òÃæ¿´¤È¤·¤¿»Í³Ñ·Á¤òÀ½ºî¤¹¤ë
+ basic_quadrangle( const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ )
+ : pos(), a1(a1_), a2(a2_), a3(a3_), a4(a4_) {}
+
+ // °ÌÃÖ¥Ù¥¯¥È¥ë£´¤Ä¤«¤é»Í³Ñ·Á¤òÀ½ºî¤¹¤ë¡£
+ // Ãæ¿´¤Ï£´ÅÀ¤ÎÊ¿¶Ñ¡¢¤¹¤Ê¤ï¤Á½Å¿´
+ basic_quadrangle( const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ )
+ {
+ pos = midpoint( midpoint( a1_, a2_ ), midpoint( a3_, a4_ ) );
+
+ a1 = a1_ - pos;
+ a2 = a2_ - pos;
+ a3 = a3_ - pos;
+ a4 = a4_ - pos;
+ }
+
+ // Á´Í×ÁǤò»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ )
+ : pos(pos_), a1(a1_), a2(a2_), a3(a3_), a4(a4_) {}
+
+ // Á´Í×ÁǤò°ÌÃÖ¥Ù¥¯¥È¥ë¤Ç»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ )
+ : pos(pos_), a1( a1_ - pos ), a2( a2_ - pos ), a3( a3_ - pos ), a4( a4_ - pos ) {}
+
+ template<typename T>
+ basic_quadrangle( const basic_quadrangle<T>& src )
+ : pos(src.pos), a1(src.a1), a2(src.a2), a3(src.a3), a4(src.a4) {}
+
+
+ // ³ÆĺÅÀ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤ò»»½Ð
+ pos_type vertex1() const { return pos + a1; }
+ pos_type vertex2() const { return pos + a2; }
+ pos_type vertex3() const { return pos + a3; }
+ pos_type vertex4() const { return pos + a4; }
+
+ // operator[]
+ pos_type operator[]( std::size_t index ) const
+ {
+ using namespace std;
+
+ switch( index )
+ {
+ case 0:
+ return vertex1();
+
+ case 1:
+ return vertex2();
+
+ case 2:
+ return vertex3();
+
+ case 3:
+ return vertex4();
+
+ default:
+ assert( !"should not get here." );
+
+ }
+ }
+ pos_type at( std::size_t index ) const
+ {
+ if( index > size() )
+ {
+ throw std::out_of_range();
+ }
+
+ return operator[](index);
+ }
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ basic_quadrangle& shift( const vec_type& d )
+ {
+ pos += d;
+
+ return *this;
+ }
+ friend basic_quadrangle shift( const basic_quadrangle& target, const vec_type& d )
+ {
+ basic_quadrangle temp = target;
+ return temp.shift(d);
+ }
+
+ // ĺÅÀ¤Î°ÌÃÖ¤òÊѤ¨¤º¡¢Ãæ¿´¤òÊѹ¹
+ basic_quadrangle& move_center( const pos_type& center )
+ {
+ vec_type d = pos - center;
+
+ pos = center;
+ a1 += d;
+ a2 += d;
+ a3 += d;
+ a4 += d;
+
+ return *this;
+ }
+ basic_quadrangle& move_center( const vec_type& d )
+ {
+ pos += d;
+ a1 -= d;
+ a2 -= d;
+ a3 -= d;
+ a4 -= d;
+
+ return *this;
+ }
+ // °ú¿ô¤Ê¤·¤À¤È½Å¿´¤Ë»ý¤Ã¤Æ¤¤¤¯
+ basic_quadrangle& move_center()
+ {
+ basic_quadrangle temp( vertex1(), vertex2(), vertex3(), vertex4() );
+ *this = temp;
+ return *this;
+ }
+
+ // ²óž
+ template<typename Angle>
+ basic_quadrangle& rotate( const Angle& theta )
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(theta), cos(theta) );
+ }
+ basic_quadrangle& rotate( real_type s, real_type c )
+ {
+ a1.rotate( s, c );
+ a2.rotate( s, c );
+ a3.rotate( s, c );
+ a4.rotate( s, c );
+
+ return *this;
+ }
+ template<typename Angle>
+ friend basic_quadrangle rotate( const basic_quadrangle& x, const Angle& theta )
+ {
+ basic_quadrangle temp = x;
+ return temp.rotate(theta);
+ }
+ friend basic_quadrangle rotate( const basic_quadrangle& x, real_type s, real_type c )
+ {
+ basic_quadrangle temp = x;
+ return temp.rotate( s, c );
+ }
+
+ };
+ typedef basic_quadrangle<double> quadrangle;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_RECT_HPP_
+#define GINTENLIB_PLANE_INCLUDED_RECT_HPP_
+
+/*
+
+ <gintenlib/plane/rect.hpp>
+
+ rect ¡§ Æ󼡸µ¶õ´Ö¾å¤Î¶ë·Á
+
+ Àë¸À¡§
+ // rect : ¶ë·Á
+ template<typename Real>
+ struct basic_rect
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ real_type x1, y1, x2, y2;
+
+ basic_rect();
+ basic_rect( real_type x1_, real_type y1_, real_type x2_, real_type y2_ );
+
+ template<typename T>
+ basic_rect( const basic_rect<T>& src );
+
+ // operator[]
+ // ĺÅÀ¤ÎºÂɸ¤òÊÖ¤·¤Þ¤¹¡£
+ pos_type operator[]( std::size_t index ) const;
+
+ pos_type at( std::size_t index ) const;
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ // ¤³¤Î¶ë·Á¼«¿È¤ò¥·¥Õ¥È¤µ¤»¤Þ¤¹¡£
+ basic_rect& shift( const vec_type& d );
+ // friend ÈǤϥ³¥Ô¡¼¤·¤Æ¤«¤é¥·¥Õ¥È¤·¤Þ¤¹¡£
+ friend basic_rect shift( const basic_rect& target, const vec_type& d );
+
+ // ²óž
+ // ¤³¤Î¶ë·Á¼«¿È¤ò²óž¤µ¤»¤¿¤¤¤¬¡¢¤½¤¦¤¹¤ë¤È¶ë·Á¤Ç¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¦¤Î¤Ç¡¢
+ // ¤ä¤à¤Ê¤¯»Í³Ñ·Á¤È¤·¤Æ¥³¥Ô¡¼¤·¤Æ¤«¤é²óž¤µ¤»¤Þ¤¹¡£
+ // Angle ÈǤϳÑÅÙ¤«¤é¥µ¥¤¥ó¥³¥µ¥¤¥ó¤òµá¤á¤Æ²óž¡¢
+ // s, c ÈǤϥµ¥¤¥ó¥³¥µ¥¤¥óÃͤ«¤éľÀܲ󞤵¤»¤Þ¤¹¡£
+ template<typename Angle>
+ basic_quadrangle<Real> rotate( const Angle& theta ) const;
+ basic_quadrangle<Real> rotate( real_type s, real_type c ) const;
+ template<typename Angle>
+ friend basic_quadrangle<Real> rotate( const basic_rect& x, const Angle& theta );
+ basic_quadrangle<Real> rotate( const basic_rect& x, real_type s, real_type c );
+
+ };
+ typedef basic_rect<double> rect;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¶õ´Ö¾å¤Î¡¢°ÌÃ֤γÎÄꤷ¤¿¶ë·Á¤òɽ¤¹¥¯¥é¥¹¡£
+ ²óž¤µ¤»¤ë¤È»Í³Ñ·Á¤ËÊѲ½¤¹¤ë°Ê³°¤ÏÉáÄ̤«¤È¡£
+
+*/
+
+#include <cstddef>
+#include <cassert>
+#include <stdexcept>
+
+#include "fwd.hpp"
+#include "vector.hpp"
+#include "point.hpp"
+#include "quadrangle.hpp"
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // rect : ¶ë·Á
+ template<typename Real>
+ struct basic_rect
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ real_type x1, y1, x2, y2;
+
+ basic_rect()
+ : x1(), y1(), x2(), y2() {}
+
+ basic_rect( real_type x1_, real_type y1_, real_type x2_, real_type y2_ )
+ : x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
+
+ template<typename T>
+ basic_rect( const basic_rect<T>& src )
+ : x1(src.x1), y1(src.y1), x2(src.x2), y2(src.y2) {}
+
+ // operator[]
+ pos_type operator[]( std::size_t index ) const
+ {
+ using namespace std;
+
+ switch( index )
+ {
+ case 0:
+ return pos_type( x1, y1 );
+
+ case 1:
+ return pos_type( x2, y1 );
+
+ case 2:
+ return pos_type( x2, y2 );
+
+ case 3:
+ return pos_type( x1, y2 );
+
+ default:
+ assert( !"should not get here." );
+
+ }
+ }
+ pos_type at( std::size_t index ) const
+ {
+ if( index > size() )
+ {
+ throw std::out_of_range();
+ }
+
+ return operator[](index);
+ }
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ basic_rect& shift( const vec_type& d )
+ {
+ x1 += d.x;
+ y1 += d.y;
+ x2 += d.x;
+ y2 += d.y;
+
+ return *this;
+ }
+ friend basic_rect shift( const basic_rect& target, const vec_type& d )
+ {
+ basic_rect temp = target;
+ return temp.shift(d);
+ }
+
+ // ²óž
+ template<typename Angle>
+ basic_quadrangle<Real> rotate( const Angle& theta ) const
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(theta), cos(theta) );
+ }
+ basic_quadrangle<Real> rotate( real_type s, real_type c ) const
+ {
+ pos_type center( (x1 + x2) / 2, (y1 + y2) / 2 );
+ real_type w = (x2 - x1) / 2, h = (x2 - x1) / 2;
+ real_type sw = s * w, sh = s * h, cw = c * w, ch = c * h;
+
+ vec_type p1( -cw - sh, -ch + sw ), p2( cw - sh, -ch - sw );
+
+ return basic_quadrangle<Real>( center, p1, p2, -p1, -p2 );
+ }
+ template<typename Angle>
+ friend basic_quadrangle<Real> rotate( const basic_rect& x, const Angle& theta )
+ {
+ return x.rotate(theta);
+ }
+ basic_quadrangle<Real> rotate( const basic_rect& x, real_type s, real_type c )
+ {
+ return x.rotate( s, c );
+ }
+
+ };
+ typedef basic_rect<double> rect;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_RECT_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
+#define GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
+
+/*
+
+ <gintenlib/plane/vector.hpp>
+
+ vector ¡§ Æ󼡸µ¥Ù¥¯¥È¥ë
+
+ Àë¸À¡§
+ template< typename Real >
+ struct basic_vector
+ : private boost::equality_comparable< basic_vector<Real> >,
+ private boost::additive< basic_vector<Real> >,
+ private boost::multiplicative< basic_vector<Real>, Real >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_vector();
+ basic_vector( real_type x_, real_type y_ );
+
+ template<typename T>
+ basic_vector( const basic_vector<T>& src );
+
+ template<typename T>
+ basic_vector( const std::pair<T, T>& src );
+
+ // ±é»»»Ò¿½ÅÄêµÁ
+ // ¤½¤ì¤¾¤ì¸«¤¿¤Þ¤ó¤Þ¤Ç¤¹¡£operator+ ¤È¤«¤Ï boost:: operators ¤Ë¤è¤Ã¤Æ³Æ¼ï¼«Æ°ÄêµÁ¤µ¤ì¤Þ¤¹¡£
+ basic_vector& operator+=( const basic_vector& rhs );
+ basic_vector& operator-=( const basic_vector& rhs );
+ basic_vector operator-() const;
+ basic_vector& operator*=( real_type rhs );
+ basic_vector& operator/=( real_type rhs );
+ bool operator==( const basic_vector& rhs ) const;
+
+ // 2-Norm
+ real_type norm() const;
+ friend real_type norm( const basic_vector& target );
+
+ // ÀäÂÐÃÍ
+ real_type absolute() const;
+ friend real_type absolute( const basic_vector& target );
+
+ // Àµµ¬²½
+ // Àµµ¬²½¤·¤¿·ë²Ì¤òÊÖ¤¹¤Î¤Ç¤Ï¤Ê¤¯¡¢¤³¤Î¥Ù¥¯¥È¥ë¼«ÂΤòÀµµ¬²½¤·¤Þ¤¹¡£
+ basic_vector& normalize();
+ // friend ÈǤϥ³¥Ô¡¼¤·¤Æ¤«¤éÀµµ¬²½¤·¤Þ¤¹¡£
+ friend basic_vector normalized( const basic_vector& x );
+
+ // ÊгÑ
+ real_type argument() const;
+ friend real_type argument( const basic_vector& x );
+
+ // ÆâÀÑ
+ real_type dot( const basic_vector& rhs ) const;
+ friend real_type dot( const basic_vector& lhs, const basic_vector& rhs );
+ friend real_type operator*( const basic_vector& lhs, const basic_vector& rhs );
+
+ // ¥í¡¼¥Æ¡¼¥È¡£²óž¤µ¤»¤¿·ë²Ì¤òÊÖ¤¹¤Î¤Ç¤Ï¤Ê¤¯¡¢¤³¤Î¥Ù¥¯¥È¥ë¼«ÂΤò²ó¤·¤Þ¤¹¡£
+ // ³ÑÅÙ»ØÄê¥Ð¡¼¥¸¥ç¥ó¡£¥Æ¥ó¥×¥ì¡¼¥È¤Ê¤Î¤Ï¡¢gintenlib::plane::angle ¤âÅϤ»¤ë¤è¤¦¤Ë¡¢¤Ç¤¹¡£
+ template< typename Angle >
+ basic_vector& rotate( const Angle& angle );
+ // ¥µ¥¤¥ó¤È¥³¥µ¥¤¥ó¤ò»ØÄꤷ¤¿¥Ð¡¼¥¸¥ç¥ó¡£¹â®¤Ç¤¹¡£
+ basic_vector& rotate( real_type s, real_type c );
+
+ // ¾åÆó¤Ä¤Î friend ÈÇ¡£¥³¥Ô¡¼¤·¤Æ¤«¤é²ó¤·¤Þ¤¹¡£
+ template< typename Angle >
+ friend basic_vector rotate( const basic_vector& target, const Angle& angle );
+ friend basic_vector rotate( const basic_vector& target, real_type s, real_type c );
+ };
+ typedef basic_vector<double> vector;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¤ÎÁêÂÐ¥Ù¥¯¥È¥ë¤òɽ¤¹¥¯¥é¥¹¡£
+ ÀäÂÐÃÍ·×»»¡¢Êгѷ׻»¡¢Àµµ¬²½¡¢²óž¤Ê¤É¡¢¤È¤ê¤¢¤¨¤º°ìÄ̤êɬÍפ½¤¦¤Ê¤â¤Î¤Ï·¤¨¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include "fwd.hpp"
+
+#include <cmath>
+#include <utility>
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ template< typename Real >
+ struct basic_vector
+ : private boost::equality_comparable< basic_vector<Real> >,
+ private boost::additive< basic_vector<Real> >,
+ private boost::multiplicative< basic_vector<Real>, Real >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_vector()
+ : x(), y() {}
+
+ basic_vector( real_type x_, real_type y_ )
+ : x(x_), y(y_) {}
+
+ template<typename T>
+ basic_vector( const basic_vector<T>& src )
+ : x(src.x), y(src.y) {}
+
+ template<typename T>
+ basic_vector( const std::pair<T, T>& src )
+ : x(src.first), y(src.second) {}
+
+ // ±é»»»Ò¿½ÅÄêµÁ
+ basic_vector& operator+=( const basic_vector& rhs )
+ {
+ x += rhs.x;
+ y += rhs.y;
+
+ return *this;
+ }
+ basic_vector& operator-=( const basic_vector& rhs )
+ {
+ x -= rhs.x;
+ y -= rhs.y;
+
+ return *this;
+ }
+ basic_vector operator-() const
+ {
+ return basic_vector( -x, -y );
+ }
+ basic_vector& operator*=( real_type rhs )
+ {
+ x *= rhs;
+ y *= rhs;
+
+ return *this;
+ }
+ basic_vector& operator/=( real_type rhs )
+ {
+ x /= rhs;
+ y /= rhs;
+
+ return *this;
+ }
+ bool operator==( const basic_vector& rhs ) const
+ {
+ return ( x == rhs.x ) && ( y == rhs.y );
+ }
+
+ // 2-Norm
+ real_type norm() const
+ {
+ return x * x + y * y;
+ }
+ friend real_type norm( const basic_vector& target )
+ {
+ return target.norm();
+ }
+
+ // ÀäÂÐÃÍ
+ real_type absolute() const
+ {
+ return std::sqrt( x * x + y * y );
+ }
+ friend real_type absolute( const basic_vector& target )
+ {
+ return target.absolute();
+ }
+
+ // Àµµ¬²½
+ basic_vector& normalize()
+ {
+ real_type r = absolute();
+
+ if( r == 0 )
+ {
+ x = 1;
+ y = 0;
+ }
+ else
+ {
+ x /= r;
+ y /= r;
+ }
+
+ return *this;
+ }
+ friend basic_vector normalized( const basic_vector& x )
+ {
+ basic_vector temp = x;
+ temp.normalize();
+ return temp;
+ }
+
+ // ÊгÑ
+ real_type argument() const
+ {
+ if( x == 0 && y == 0 )
+ {
+ return 0;
+ }
+ return std::atan2( y, x );
+ }
+ friend real_type argument( const basic_vector& x )
+ {
+ return x.argument();
+ }
+
+ // ÆâÀÑ
+ real_type dot( const basic_vector& rhs ) const
+ {
+ return x * rhs.x + y * rhs.y;
+ }
+ friend real_type dot( const basic_vector& lhs, const basic_vector& rhs )
+ {
+ return lhs.dot(rhs);
+ }
+ friend real_type operator*( const basic_vector& lhs, const basic_vector& rhs )
+ {
+ return lhs.dot(rhs);
+ }
+
+ // ¥í¡¼¥Æ¡¼¥È
+ template< typename Angle >
+ basic_vector& rotate( const Angle& angle )
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(angle), cos(angle) );
+ }
+ basic_vector& rotate( real_type s, real_type c )
+ {
+ real_type sx = s*x, sy = s*y, cx = c*x, cy = c*y;
+
+ x = cx - sy;
+ y = sx + cy;
+
+ return *this;
+ }
+ template< typename Angle >
+ friend basic_vector rotate( const basic_vector& target, const Angle& angle )
+ {
+ basic_vector temp = target;
+ temp.rotate( angle );
+ return temp;
+ }
+ friend basic_vector rotate( const basic_vector& target, real_type s, real_type c )
+ {
+ basic_vector temp = target;
+ temp.rotate( s, c );
+ return temp;
+ }
+ };
+ typedef basic_vector<double> vector;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
--- /dev/null
+#ifndef GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
+#define GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
+
+/*
+
+ <gintenlib/preprocessor/dequote.hpp>
+
+ dequote ¡§ ¥Þ¥¯¥í¤Î°ú¿ô¤Ë¥Æ¥ó¥×¥ì¡¼¥È¤ò»È¤¦¾ì¹ç¤Î¥æ¡¼¥Æ¥£¥ê¥Æ¥£
+
+ Àë¸À¡§
+ namespace gintenlib
+ {
+ namespace detail_
+ {
+ template<typename T>
+ struct dequote_helper{};
+
+ template<typename Arg>
+ struct dequote_helper<void (*)(Arg)>
+ {
+ typedef Arg type;
+ };
+
+ }
+ }
+
+ #define GINTENLIB_DEQUOTE( QUOTED_TYPE ) \
+ ::gintenlib::detail_::dequote_helper<void (*)QUOTED_TYPE>::type
+
+ »ÈÍÑÎ㡧
+ // Îã¤È¤·¤Æ¡¢Í¿¤¨¤é¤ì¤¿·¿¤Ë¤¿¤¤¤·¡¢¤½¤Î·¿Æó¤Ä¤Î¥Ú¥¢¤Î·¿¤òÊÖ¤¹¥Þ¥¯¥í¤òÄêµÁ¤·¤Æ¤ß¤ë
+ // ¥Æ¥ó¥×¥ì¡¼¥È¤Ø¤ÎÊÌ̾ÉÕ¤±¤¬ C++ ɸ½à¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤ÐÉÔÍפǤ¹¤¬¡¢¸½¾õ̵Íý¤Ê¤Î¤Ç
+
+ // ¤Þ¤º¥À¥á¤ÊÎã
+ // #define PAIR_OF( type ) std::pair<type, type>
+ // ¤³¤ì¤À¤È¡¢ PAIR_OF( std::pair<int, double> ) ¤Î¤è¤¦¤Ê
+ // Ê£¿ô¤Î°ú¿ô¤ò»ý¤Ä¥Æ¥ó¥×¥ì¡¼¥È·¿¤ò¡¢¥Þ¥¯¥í¤Î°ú¿ô¤È¤·¤ÆÅϤ¹¤³¤È¤¬½ÐÍè¤Ê¤¤
+ // ¡Ê¥×¥ê¥×¥í¥»¥Ã¥µ¤Ï¥Æ¥ó¥×¥ì¡¼¥È¤Î»°³Ñ³ç¸Ì¤ò̵»ë¤¹¤ë¤¿¤á¡¢Æó°ú¿ô¥Þ¥¯¥í¤È´ª°ã¤¤¤µ¤ì¤ë¡Ë
+
+ // ¤½¤³¤Ç¡¢¤³¤¦½ñ¤¯
+ #define PAIR_OF( quoted_type ) \
+ std::pair< \
+ typename GINTENLIB_DEQUOTE( quoted_type ), \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >
+ // GINTENLIB_DEQUOTE ¤Ï ¤Ê¤ó¤¿¤é::type ¤È¤¤¤¦¤Õ¤¦¤ËŸ³«¤µ¤ì¤ë¤Î¤Ç
+ // ɬÍפ˱þ¤¸¤Æ typename ¥¡¼¥ï¡¼¥É¤òÉÕ¤±¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤
+ // ÂçÂΤξì¹ç¤Ï¤È¤ê¤¢¤¨¤º typename ¤òÉÕ¤±¤ì¤Ð£Ï£Ë
+
+ // »ÈÍѤ¹¤ë¤È¤¤Ï¡¢
+ PAIR_OF(( std::pair<int, double> )) hoge;
+ // ¤³¤Î¤è¤¦¤Ë·¿Ì¾¤òÆó½Å³ç¸Ì¤Ç¤¯¤ë¤à
+
+ ²òÀ⡧
+ ¤³¤Î¥Þ¥¯¥í¤¬²¿¤ò¤·¤Æ¤¤¤ë¤«¤Ï¡¢Îã¤ò¸«¤ì¤Ðʬ¤«¤ë¤È»×¤¦¤Î¤Ç¡¢Ê¬¤«¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+ ´Êñ¤Ë¸À¤¨¤Ð¡¢¡Ö ( ·¿Ì¾ ) ¡×¤È¤¤¤¦¥·¥ó¥Ü¥ëÎó¤ò¼õ¤±¼è¤ê¡¢³ç¸Ì¤ò³°¤¹¥Þ¥¯¥í¤Ç¤¹¡£
+ ¼ÂÁõÊýË¡¤Ç¤¹¤¬¡¢¼Â¤Ï¡Ö ( ¤Ê¤ó¤¿¤é ) ¡×¤Î³ç¸Ì¤òľÀܳ°¤¹ÊýË¡¤Ï¡ÊÃΤꤨ¤ëÈϰϤǤϡ˸ºß¤·¤Ê¤¤¤Î¤Ç¡¢
+ ¡Ö void (*)( ·¿Ì¾ ) ¡×¤È¤¤¤¦É½¸½¤Ëľ¤·¤Æ¡¢´Ø¿ô¤Î°ú¿ô¡¢¤È¤¤¤¦·Á¤Ç·¿Ì¾¤òʬΥ¤·¤Æ¤¤¤Þ¤¹¡£
+ ¤½¤¦¤¤¤¦¼ÂÁõ¤ÎÅÔ¹ç¾å¡¢´Ø¿ô·¿¤ò¥Æ¥ó¥×¥ì¡¼¥È¤Î°ú¿ô¤È¤·¤ÆÆü첽¤Ç¤¤ë¥³¥ó¥Ñ¥¤¥é¤Ç¤·¤«Æ°ºî¤·¤Þ¤»¤ó¡£
+ ¤Þ¤¿¡¢·¿Ì¾¼«¿È¤ËŸ³«¤µ¤ì¤ë¤ï¤±¤Ç¤â¤Ê¤¤¤Î¤Ç¡¢É¬Íפ˱þ¤¸¤Æ typename ½¤¾þ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+*/
+
+namespace gintenlib
+{
+ namespace detail_
+ {
+ template<typename T>
+ struct dequote_helper {};
+
+ template<typename Arg>
+ struct dequote_helper<void (*)(Arg)>
+ {
+ typedef Arg type;
+ };
+
+ // ËÜÂÎ
+ // QUOTED_TYPE ¤Ï ( DEQUOTED_TYPE ) ¤Î·Á¤Ç»ØÄꤵ¤ì¤ë
+ // dequote_helper<void (*)( DEQUOTED_TYPE )>::type ¤Ï DEQUOTED_TYPE ·¿¤È¤Ê¤ë
+ #define GINTENLIB_DEQUOTE( QUOTED_TYPE ) \
+ ::gintenlib::detail_::dequote_helper<void (*)QUOTED_TYPE>::type
+
+ } // namespace detail_
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
--- /dev/null
+#ifndef GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
+#define GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
+
+/*
+
+ <gintenlib/preprocessor/enable_if.hpp>
+
+ preprocessor.enable_if ¡§ ¤é¤¯¤Á¤ó enable_if
+
+ Àë¸À¡§
+ #define GINTENLIB_ENABLE_IF (( condition )) ¡Á
+ #define GINTENLIB_DISABLE_IF(( condition )) ¡Á
+
+ »ÈÍÑÎ㡧
+ // d_enable_if.hpp ¤ÎÎã¤ò¤ä¤Ã¤Ä¤±¤ë
+ // using namespace gintenlib; // ¤³¤ó¤Ê¤ÎɬÍפʤ¤
+
+ // °ú¿ô¤ò Target ·¿¤Ø°ÅÌÛÊÑ´¹¤¹¤ë
+ // Ä̾ïÈÇ¡¢Target ¤¬»²¾È·¿¤Ç¤Ê¤±¤ì¤Ð¤³¤Ã¤Á¤¬¸Æ¤Ð¤ì¤ë
+ // ÂèÆó°ú¿ô¤ËÃíÌÜ¡£¤Á¤Ê¤ß¤Ë¤³¤Î°ú¿ô¤Ï¥À¥ß¡¼¤Ê¤Î¤Ç̵»ë¤·¤Æ£Ï£Ë
+ template< typename Target, typename Source >
+ inline Target cast( const Source& src,
+ GINTENLIB_DISABLE_IF(( boost::is_reference<Target> )) )
+ {
+ return src;
+ }
+
+ // »²¾ÈÈÇ
+ template< typename Target, typename Source >
+ inline Target cast( Source& src,
+ GINTENLIB_ENABLE_IF(( boost::is_reference<Target> )) )
+ {
+ return src;
+ }
+
+ // c.f.) d_enable_if.hpp ¤ÎÎã
+ //
+ // // »²¾ÈÈÇ
+ // template< typename Target, typename Source >
+ // inline Target cast( Source& src,
+ // typename d_enable_if< boost::is_reference<Target> >::type = dummy_arg_t() )
+ // {
+ // return src;
+ // }
+ //
+ // Èæ³Ó¤·¤Æ¤ß¤ë¤È¡¢¤É¤ì¤À¤±³Ú¤«Ê¬¤«¤ë¤Ï¤º
+
+ ²òÀ⡧
+ ´Ø¿ô¥ª¡¼¥Ð¡¼¥í¡¼¥ÉÍѤΠenable_if ¤ò¤é¤¯¤Á¤ó¤Ë¤¹¤ë¤¿¤á¤Î¥Þ¥¯¥í¤Ç¤¹¡£
+ ¼ÂºÝ¤Ë¤É¤Î¤è¤¦¤ËŸ³«¤µ¤ì¤Æ¤¤¤ë¤«¤Ï²¼¤ÎÎã¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+ ¤Þ¡¼¿¿ÌÌÌܤ˽ñ¤¤¤Æ¤âÎɤ¤¤Î¤Ç¤¹¤¬¡¢
+ typename gintenlib::d_enable_if< ¤Ê¤ó¤¿¤é, gintenlib::dummy_arg_t >::type
+ = gintenlib::dummy_arg_t()
+ ÀµÄ¾¤³¤ó¤ÊŤ¤¥½¡¼¥¹¥³¡¼¥É¤Ê¤ó¤Æ½ñ¤¤¤Æ¤é¤ì¤Þ¤»¤ó¤«¤é¤Í¡£
+ d_enable_if ¤È dummy_arg_t ¤Î¸ºß°ÕµÁ¤Ï <gintenlib/d_enable_if.hpp> ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ »È¤¤Êý¤Ï¡¢¾å¤ÎÎã¤ÎÄ̤ꡢenable_if ¤Î <> ¤ÎÃæ¤Îµ½Ò¤ò¡ÖÆó½Å³ç¸Ì¤Ç¤¯¤¯¤Ã¤Æ¡×¥Þ¥¯¥í¤ËÅϤ·¤Æ¡¢
+ ´Ø¿ô¤Î°ú¿ô¥ê¥¹¥È¤ÎºÇ¸å¤ËÃÖ¤¤¤Æ¤ª¤¯¤À¤±¡£´Êñ¤Ç¤¹¡£
+ ÉáÄÌ¡¢¤³¤¦¤¤¤¦¡Ö¥á¥¿´Ø¿ô¤ò°ú¿ô¤Ë¼è¤ë¡×¥Þ¥¯¥í¤Ã¤Æ¤Î¤Ï¡¢¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¥ê¥¹¥È¤Î¥«¥ó¥Þ¤¬¼ÙËâ¤ò¤·¤Æ
+ Àµ¾ï¤Ë¥Þ¥¯¥íŸ³«¤µ¤ì¤Ê¤«¤Ã¤¿¤ê¤¹¤ë¤Î¤Ç¤¹¤¬¡¢¤³¤ì¤Ë´Ø¤·¤Æ¤Ïµ¤¤Ë¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+ ¥æ¡¼¥¶Â¦¤ÇÃí°Õ¤¹¤Ù¤¤Ï°ìÅÀ¤Î¤ß¡¢¥Þ¥¯¥í¤Î°ú¿ô¤Ïɬ¤ºÆó½Å³ç¸Ì¤Ç¤¯¤ë¤à¤³¤È¡£
+ ¤½¤³¤Ë¤µ¤¨µ¤¤ò¤Ä¤±¤ì¤Ð´Êñ¤Ë´Ø¿ô¸Æ¤Ó½Ð¤·¤ÎÀÚ¤êÂؤ¨¤¬½ÐÍè¤Þ¤¹¡£ÊØÍø¤Ç¤¹¡£
+
+*/
+
+#include "../d_enable_if.hpp"
+#include "dequote.hpp"
+
+namespace gintenlib
+{
+ // GINTENLIB_DEQUOTE(( TYPE )) ¤Ï¡¢ ¤Ê¤ó¤È¤«<¡Á>::type ¤È¤¤¤¦·Á¤ÇŸ³«¤µ¤ì¤ë
+ // ¤³¤Î type ¤¬ TYPE ·¿¤ËÄêµÁ¤µ¤ì¤ë¤è¤¦¤Ê»Å³Ý¤±¤È¤Ê¤Ã¤Æ¤¤¤ë
+ // ¤è¤Ã¤Æ GINTENLIB_DEQUOTE Á°¤Î typename ¤Ïɬ¿Ü
+ #define GINTENLIB_ENABLE_IF( quoted_type ) \
+ typename ::gintenlib::d_enable_if< \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >::type = ::gintenlib::dummy_arg_t()
+
+ #define GINTENLIB_DISABLE_IF( quoted_type ) \
+ typename ::gintenlib::d_disable_if< \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >::type = ::gintenlib::dummy_arg_t()
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_REFERENCE_COUNTER_HPP_
+#define GINTENLIB_INCLUDED_REFERENCE_COUNTER_HPP_
+
+/*
+
+ <gintenlib/reference_counter.hpp>
+
+ reference_counter ¡§ boost::intrusive_ptr ÍÑ¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®
+
+ Àë¸À¡§
+ template<typename Derived, bool multiplely_successable = false >
+ class reference_counter
+ {
+ public:
+ // »²¾È¤òÁý¤ä¤¹
+ void AddRef() const;
+ // »²¾È¤ò¸º¤é¤¹¡£¥¼¥í¤Ë¤Ê¤Ã¤¿¤é¼«Æ°²òÊü
+ void Release() const;
+
+ protected:
+ // ½é´ü¥«¥¦¥ó¥È¤ò»ØÄꤷ¤Æ½é´ü²½
+ reference_counter( int initial_count = 0 );
+ // ¥³¥Ô¡¼¤Ï°ì±þ²Äǽ¤Ë¤¹¤ë
+ // ¥«¥¦¥ó¥È¤ÏÆ°¤«¤Ê¤¤
+ reference_counter( const reference_counter& );
+ // ²òÊü
+ ~reference_counter();
+
+ private:
+ // ÂåÆþ¤Ï½ÐÍè¤Ê¤¤
+ void operator=( const reference_counter& );
+
+ };
+
+ template< typename T, bool b >
+ inline void intrusive_ptr_add_ref( const reference_counter<T, b>* ptr );
+ template< typename T, bool b >
+ inline void intrusive_ptr_release( const reference_counter<T, b>* ptr );
+
+ »ÈÍÑË¡¡§
+ class hoge : public gintenlib::reference_counter<hoge>
+ {
+ // ŬÅö¤ËÃæ¿È¤òµ½Ò
+ };
+
+ boost::intrusive_ptr<hoge> p = new hoge;
+ // or gintenlib::com_ptr<hoge> p( new hoge );
+
+ // ¿½Å·Ñ¾µ¤â½ÐÍè¤Þ¤¹¡£¤½¤Î¾ì¹ç¤Ï¥Æ¥ó¥×¥ì¡¼¥ÈÂèÆó°ú¿ô¤Ë true ¤òÅϤ·¤Æ¤¯¤À¤µ¤¤
+ struct base1 : gintenlib::reference_counter<base1, true>
+ {
+ // Ãæ¿È
+ };
+ struct base2 : gintenlib::reference_counter<base2, true>
+ {
+ // Ãæ¿È
+ };
+ struct derived : base1, base2
+ {
+ // Ãæ¿È
+ };
+
+ µ¡Ç½¡§
+ »ÈÍÑË¡¤ò¸«¤ì¤Ð°ìÌÜÎÆÁ³¤Ç¤·¤ç¤¦¡£¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤Ë¼«¿È¤òÅϤ·¤Æ·Ñ¾µ¤¹¤ì¤ÐOK¤Ç¤¹¡£
+ ÂèÆó¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤Ï¡¢Â¿½Å·Ñ¾µ¤¬½ÐÍè¤ë¤«Èݤ«¡£true¤òÅϤ»¤Ð¿½Å·Ñ¾µ¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï false ¤Ç¤¹¡£¤³¤Î¾ì¹ç¡¢²¾ÁÛ´Ø¿ô¥Æ¡¼¥Ö¥ë¤Ï»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó¡£
+ ¤è¤Ã¤Æ¡¢Èó¿½Å·Ñ¾µÈǤǷѾµ¤ò¤·¤¿¤¤¾ì¹ç¡¢¥Ç¥¹¥È¥é¥¯¥¿¤ò virtual »ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ ¿½Å·Ñ¾µÈǤǤϡ¢¤½¤¦¤¤¤Ã¤¿µ¤¸¯¤¤¤ò¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£¤¬¡¢¤½¤Îʬ¥³¥¹¥È¤¬¹â¤¤¤Ç¤¹¡£
+
+ È÷¹Í¡§
+ ¤³¤Î¥¯¥é¥¹¤Ï¡¢Åö½é¤Ï noncopyable ¤È¤·¤ÆÀ½ºî¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¡£
+ ¤·¤«¤·¡¢ÇÉÀ¸Àè¤Ç¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤ò¼«Æ°À¸À®¤·¤Æ¤¯¤ì¤Ê¤¤¤Î¤ÏÌÌÅݤʤΤǡ¢¥³¥Ô¡¼¤Ë¸Â¤ê²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+ ¤³¤ÎºÝ¡¢»²¾È¥«¥¦¥ó¥È¤Ë´Ø¤·¤Æ¤Ï¡¢¥³¥Ô¡¼¸µ¤Ë¤Ï̵´Ø·¸¤Ë 0 ¤Ë½é´ü²½¤µ¤ì¤Þ¤¹¡£
+ ¤Þ¤¿ÂåÆþ±é»»¤Ï¡Ö copy ¤·¤Æ swap ¡×¤È¤¤¤¦Îã³°°ÂÁ´¤ÊÊýË¡¤¬¤¢¤ë¤Î¤Ç¡¢¤½¤Á¤é¤ò¿ä¾©¤¹¤ë°ÕÌ£¤Ç¶Ø»ß¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include <cassert>
+#include <algorithm>
+
+namespace gintenlib
+{
+ // Èó²¾ÁۥС¼¥¸¥ç¥ó¡£¥µ¥¤¥º¤ä®ÅÙ¤ÎÌ̤ǺÇŬ²½¤µ¤ì¤Þ¤¹¤¬¡¢Â¿½Å·Ñ¾µ¤Ï½ÐÍè¤Þ¤»¤ó
+ template<typename Derived, bool multiplely_successable = false >
+ struct reference_counter
+ {
+ void AddRef() const
+ {
+ using namespace std;
+ assert( count >= 0 );
+
+ ++count;
+ }
+ void Release() const
+ {
+ using namespace std;
+ assert( count > 0 );
+
+ if( --count == 0 )
+ {
+ delete static_cast<const Derived*>(this);
+ }
+ }
+
+ // »²¾È¥«¥¦¥ó¥È¤ò¼èÆÀ
+ int use_count() const { return count; }
+
+ protected:
+ reference_counter( int initial_count = 0 ) : count(initial_count) {}
+ ~reference_counter()
+ {
+ using namespace std;
+ assert( count == 0 );
+ }
+
+ // ¥³¥Ô¡¼¤Ï°ì±þ²Äǽ¤Ë¤¹¤ë
+ reference_counter( const reference_counter& ) : count(0) {}
+
+ private:
+ mutable int count;
+ // ÂåÆþ¤Ï½ÐÍè¤Ê¤¤
+ void operator=( const reference_counter& );
+
+ };
+
+ // boost::intrusive_ptr ÍѤΥ¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹
+ // reference_counter<T> ¤Ï reference_counter<T, false> ¤Î°ÕÌ£¤Ê¤Î¤Ç
+ // ²¾Á۷ѾµÈǤȤ϶¥¹ç¤·¤Þ¤»¤ó
+ template< typename T >
+ inline void intrusive_ptr_add_ref( const reference_counter<T>* ptr )
+ {
+ ptr->AddRef();
+ }
+ template< typename T >
+ inline void intrusive_ptr_release( const reference_counter<T>* ptr )
+ {
+ ptr->Release();
+ }
+
+
+ // ²¾Á۷ѾµÈǤΥ١¼¥¹¥¯¥é¥¹
+ struct reference_counter_base
+ {
+ void AddRef() const
+ {
+ using namespace std;
+ assert( count >= 0 );
+
+ ++count;
+ }
+ void Release() const
+ {
+ using namespace std;
+ assert( count > 0 );
+
+ if( --count == 0 )
+ {
+ delete this;
+ }
+ }
+ // »²¾È¥«¥¦¥ó¥È¤ò¼èÆÀ
+ int use_count() const { return count; }
+
+ protected:
+ reference_counter_base( int initial_count = 0 ) : count(initial_count) {}
+ virtual ~reference_counter_base()
+ {
+ using namespace std;
+ assert( count == 0 );
+ }
+
+ // ¥³¥Ô¡¼¤Ï°ì±þ²Äǽ¤Ë¤¹¤ë
+ reference_counter_base( const reference_counter_base& ) : count(0) {}
+
+ private:
+ mutable int count;
+ // ÂåÆþ¤Ï½ÐÍè¤Ê¤¤
+ void operator=( const reference_counter_base& );
+
+ };
+
+ // ²¾Á۷ѾµÈÇËÜÂΡ£¥³¥¹¥È¤Ï¹â¤¤¤Ç¤¹¤¬¥À¥¤¥¢¥â¥ó¥É·Ñ¾µ¤Ç¤¤Þ¤¹
+ template<typename Derived>
+ struct reference_counter<Derived, true>
+ : virtual reference_counter_base
+ {
+ protected:
+ reference_counter( int initial_count = 0 )
+ : reference_counter_base(initial_count) {}
+ virtual ~reference_counter(){}
+
+ };
+
+ // ²¾Á۷ѾµÈÇ¤Ç¤Ï reference_counter_base ¤ËÂФ· add_ref/release ¤òÄêµÁ¤¹¤ë¤³¤È¤Ç
+ // ¾×Æͤ¬µ¯¤³¤é¤Ê¤¤¤è¤¦¤Ë¹©Éפµ¤ì¤Æ¤¤¤Þ¤¹
+ inline void intrusive_ptr_add_ref( const reference_counter_base* ptr )
+ {
+ ptr->AddRef();
+ }
+ inline void intrusive_ptr_release( const reference_counter_base* ptr )
+ {
+ ptr->Release();
+ }
+
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_REFERENCE_COUNTER_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_SHARED_PTR_HPP_
+#define GINTENLIB_INCLUDED_SHARED_PTR_HPP_
+
+/*
+
+ <gintenlib/shared_ptr.hpp>
+
+ shared_ptr ¡§ boost::shared_ptr ¤Î using Àë¸À
+
+ Àë¸À¡§
+ using boost::shared_ptr;
+
+ µ¡Ç½¡§
+ ñ½ã¤Ë gintenlib Æâ¤Ç boost::shared_ptr ¤ò»È¤¦µ¡²ñ¤Ï¿¤¤¤Î¤Ç¡¢
+ ͽ¤á using Àë¸À¤·¤Æ¤ª¤±¤Ð¡¢¤¤¤Á¤¤¤Á boost:: ¤È»ØÄꤷ¤Æ¤ä¤ëɬÍפ¬Ìµ¤¯¤Æ³Ú¡¢¤À¤±¤Î¥Ø¥Ã¥À¤Ç¤¹¡£
+ ¤¢¤È¤Ï TR1 ¤Ø¤ÎÂбþ¤ò¤·¤ä¤¹¤¤¤è¤¦¤Ë¡¢¤È¤¤¤¦°ÕµÁ¤â¤¢¤ê¤Þ¤¹¡£
+ ¤½¤Î¾ì¹ç¤Ï¸ß´¹À¤¬¼º¤ï¤ì¤ë²ÄǽÀ¤â¤¢¤ë¤Î¤Ç¡¢¤ä¤ë¤È¤¹¤ì¤Ð¥á¥¸¥ã¡¼¥Ð¡¼¥¸¥ç¥ó¥¢¥Ã¥×»þ¤Ç¤·¤ç¤¦¤¬¡£
+
+*/
+
+#include <boost/shared_ptr.hpp>
+
+namespace gintenlib
+{
+ using boost::shared_ptr;
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_SHARED_PTR_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_TO_SHARED_HPP_
+#define GINTENLIB_INCLUDED_TO_SHARED_HPP_
+
+/*
+
+ <gintenlib/to_shared.hpp>
+
+ to_shared ¡§ Ǥ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò shared_ptr ¤ËÊÑ´¹
+
+ Àë¸À¡§
+ // Ǥ°Õ´Ø¿ô
+ template<typename P>
+ shared_ptr<typename P::element_type> to_shared( const P& pt );
+
+ // std::auto_ptr
+ template<typename T>
+ shared_ptr<T> to_shared( std::auto_ptr<T> p );
+
+ // trivial ¤Ç¤¹¤¬ shared_ptr ¤«¤é¤â
+ template<typename T>
+ shared_ptr<T> to_shared( const shared_ptr<T>& p );
+
+ // ¤³¤ì¤Ï intrusive_to_shared.hpp Æâ¤ÇÄêµÁ
+ template<typename T>
+ shared_ptr<T> to_shared( const boost::intrusive_ptr<T>& p );
+
+ // ¤½¤Î¤Û¤«¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤Î³Æ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ËÂФ·Å¬ÀÚ¤Ê to_shared ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë
+
+ µ¡Ç½¡§
+ ³Æ¼ï¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ò shared_ptr ¤ËÊÑ´¹¤·¤Þ¤¹¡£
+ ÈÆÍÑÈǤÏÂçÉôʬ¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤òÊÑ´¹¤·¤Æ¤¯¤ì¤ë¤Ï¤º¤Ç¤¹¤¬¡¢º£¤Î¤È¤³¤íÆ°ºîÊݾã¤Ï¤Ç¤¤Þ¤»¤ó¡£
+ Æ°ºîÊݾã¤Î½ÐÍè¤Ê¤¤ÈÆÍÑÈǤò¤ï¤¶¤ï¤¶»Ä¤·¤Æ¤¤¤ëÍýͳ¤Ï¡¢Ì¾Á°¶õ´Ö¤Î¼«Æ°¾È²ñ¤ò¹Ô¤¨¤ë¤è¤¦¤Ë¤Ç¤¹¡£
+ Boost.Swap ( http://www.boost.org/doc/libs/1_41_0/libs/utility/swap.html ) ¤ÈƱ¤¸¤è¤¦¤Ë¡¢
+ gintenlib::to_shared( pt ) ¤Èµ½Ò¤µ¤ì¤¿¾ì¹ç¡¢ gintenlib ̾Á°¶õ´Ö¤À¤±¤Ç¤Ê¤¯¡¢
+ pt ¤Î¥¯¥é¥¹¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë̾Á°¶õ´Ö¤«¤é¤â to_shared ´Ø¿ô¤òõ¤·¤Æ¤¯¤ì¤Þ¤¹¡£
+
+*/
+
+#include "shared_ptr.hpp"
+#include "intrusive_to_shared.hpp"
+
+#include <cassert>
+#include <memory>
+
+// friend ´Ø¿ô¤ò»È¤¤¤ä¤¹¤¤¤è¤¦¤Ë
+// ËÜÂΤÏÊ̤Î̾Á°¶õ´Ö¤ò»È¤¦
+namespace gintenlib_to_shared_impl_
+{
+ // ¤¤¤ï¤æ¤ë¡Ö¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¡×¤òÊÝ»ý¤¹¤ë¥Û¥ë¥À
+ // shared_ptr ¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤ÎÂèÆó°ú¿ô¤È¤·¤ÆÅϤ¹ºï½ü»Ò¤È¤·¤Æ»È¤¨¤ë
+ template<typename Pointer>
+ struct to_shared_holder
+ {
+ typedef typename Pointer::element_type T;
+ typedef boost::shared_ptr<T> shared_t;
+
+ // ¹½ÃÛ
+ to_shared_holder()
+ : pt() {}
+ to_shared_holder( const Pointer& pt_ )
+ : pt( pt_ ) {}
+
+ // shared_ptr ¤Ë¤¹¤ë
+ static shared_t to_shared( const Pointer& pt_ )
+ {
+ // ¤Þ¤º null pointer ¤ËÂФ¹¤ëºÇŬ²½
+ T* p = pt_.get();
+ if( !p ){ return shared_t(); }
+
+ // ËÜÂΤÏžÁ÷
+ return to_shared_holder(pt_).to_shared();
+ }
+ // ËÜÂÎ
+ // ¤³¤ì¤ò¼Â¹Ô¤¹¤ë¤È¡¢¤³¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ï NULL ¤ËºÆÀßÄꤵ¤ì¤ë
+ shared_t to_shared()
+ {
+ using namespace std; // for assert()
+ T* p = pt.get();
+
+ // ¤¤¤Ã¤¿¤ó²¾¤Î to_shared_holder ¤ò»È¤Ã¤Æ shared_ptr ¤òºî¤ë
+ // ¤³¤³¤ÇÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¡¢²¿¤â¹Ô¤ï¤ì¤ºÈ´¤±¤ë¤Î¤Ç°ÂÁ´
+ shared_t temp( p, to_shared_holder() );
+
+ // ºî¤é¤ì¤¿ shared_ptr ¤ÎÃæ¿È¤ò¤¤¤¸¤ë
+ // ¥Ý¥¤¥ó¥È¤Ï¡¢¤³¤³¤«¤é²¾¤Î to_shared_holder ¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤ë¤Þ¤Ç¡¢Îã³°¤¬Åꤲ¤é¤ì¤Ê¤¤¤³¤È
+
+ // ¤³¤ì¤ÏÎã³°¤òÅꤲ¤Ê¤¤
+ to_shared_holder* holder = boost::get_deleter< to_shared_holder >( temp );
+ // ºî¤Ã¤¿¤Ð¤«¤ê¤Î holder ¤Î·¿¤¬ÉÔ°ìÃפʤ櫓¤Ê¤¤
+ assert( holder != 0 );
+
+ // ¤³¤ì¤âÂç¾æÉ×
+ Pointer& pt_ = holder->pt;
+ // ¤³¤ì¤¬°ìÈ֤λ³¾ì¡£ÉáÄÌ¤Ï swap ¤Ï nothrow ¤È¿®¤¸¤ë
+ swap( pt, pt_ );
+
+ // ¤³¤ì¤Ç to_shared_pointer ¤ÎÃæ¿È¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤¿
+
+ // °ì±þ³Îǧ¤¹¤ë
+ assert( pt.get() == 0 && pt_.get() == p );
+
+ // ²¿¸Î¤³¤ó¤ÊÌÌÅݤʤ³¤È¤ò¤·¤Æ¤¤¤ë¤«¤È¤¤¤¦¤È¡¢
+ // ¿¼¤¤¥³¥Ô¡¼¤ò¹Ô¤¦¥¿¥¤¥×¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤âÌäÂê¤Ê¤¯ÊÝ»ý¤Ç¤¤ë¤è¤¦¤Ë¤·¤¿¤¤¤¿¤á¡£
+ // Pointer p2 = p1; ¤Î½èÍý¤ò¤·¤¿¸å¤Ë¡¢ p1.get() == p2.get() ¤Ç¤¢¤ëÊݾڤϤʤ¤¤Î¤Ç¤¹
+
+ // ´°À®¤·¤¿ shared_ptr ¤òÊÖ¤¹
+ return temp;
+ }
+
+ // °ìÈÖÂç»ö¤Ê¤Ï¤º¤Îºï½ü´Ø¿ô¡¦¡¦¡¦¤À¤¬
+ // ¤ä¤Ã¤Æ¤ë¤³¤È¤ÏÆäË̵¤·
+ typedef void result_type;
+ void operator()( T* target ) throw ()
+ {
+ // °ì±þ¡¢Àµ¤·¤¤¥¿¡¼¥²¥Ã¥È¤òºï½ü¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¡¢¥Á¥§¥Ã¥¯¤¹¤ë
+ using namespace std;
+ assert( !pt.get() || pt.get() == target );
+
+ // ¤³¤ì¤¬¸Æ¤Ð¤ì¤¿¸å¤Ë shared_ptr ¤ÎƯ¤¤Ç¤³¤Î¥ª¥Ö¥¸¥§¥¯¥È¤¬ÇË´þ¤µ¤ì¡¢
+ // Ʊ»þ¤Ë pt ¤Î͸ú´ü¸Â¤âÀÚ¤ì¤ë¤Î¤Ç¡¢¤³¤³¤Ç¤Ï²¿¤â¤·¤Ê¤¤
+ }
+
+ private:
+ // ¥á¥ó¥Ð¤È¤·¤Æ Pointer ¤òÊÝ»ý¤¹¤ë¤Î¤Ç
+ // ¤³¤ì¤¬Â¸ºß¤¹¤ë¸Â¤ê¡¢
+ Pointer pt;
+
+ }; // to_shared_holder<Pointer>
+
+ // ¡ÖǤ°Õ¥Ý¥¤¥ó¥¿¤ÎÊÑ´¹¡×ËÜÂÎ
+ template<typename P>
+ inline boost::shared_ptr<typename P::element_type> to_shared( const P& pt )
+ {
+ return to_shared_holder<P>::to_shared( pt );
+ }
+
+} // namespace gintenlib_to_shared_impl_
+
+
+namespace gintenlib
+{
+ // ËÜÂΤÏñ¤Ê¤ëÇö¤¤¥é¥Ã¥Ñ
+ template<typename P>
+ inline shared_ptr<typename P::element_type> to_shared( const P& pt )
+ {
+ using ::gintenlib_to_shared_impl_::to_shared;
+ // ¤³¤Î using Àë¸À¤Î¤ª¤«¤²¤Ç
+ // ¤¤¤Ä¤Ç¤â gintenlib::to_shared( pt ) ¤Î·Á¤Ç»È¤¨¤ë
+
+ return to_shared( pt );
+ }
+
+ // std::auto_ptr version
+ template<typename T>
+ inline shared_ptr<T> to_shared( std::auto_ptr<T> pt )
+ {
+ return shared_ptr<T>( pt.release() );
+ }
+
+ // trivial version
+ template<typename T>
+ inline shared_ptr<T> to_shared( const shared_ptr<T>& pt )
+ {
+ return pt;
+ }
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_TO_SHARED_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_TO_STRING_HPP_
+#define GINTENLIB_INCLUDED_TO_STRING_HPP_
+
+/*
+
+ <gintenlib/to_string.hpp>
+
+ to_string ¡§ ʸ»úÎóÊÑ´¹
+
+ Àë¸À¡§
+ template<typename T>
+ std::string to_str( const T& src );
+ template<typename T>
+ std::string to_string( const T& src );
+
+ µ¡Ç½¡§
+ ʸ»úÎó¤ËÊÑ´¹¤¹¤ë¡£
+ lexical_cast¤è¤ê¡Ê¤¿¤Ö¤ó¡Ë¹â®
+
+*/
+
+#include <string>
+#include <sstream>
+
+namespace gintenlib
+{
+ template<typename T>
+ inline std::string to_string( const T& src )
+ {
+ // ½èÍý¤â¸«¤¿¤Þ¤Þ¤Ç¤¢¤ë
+ std::ostringstream oss;
+ oss << src;
+
+ return oss.str();
+ }
+ template<typename T>
+ inline std::string to_str( const T& src )
+ {
+ // ¤µ¤é¤Ë̾Á°¤òû½Ì¤¹¤ë
+ std::ostringstream oss;
+ oss << src;
+
+ return oss.str();
+ }
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_TO_STRING_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_TRIBOOL_HPP_
+#define GINTENLIB_INCLUDED_TRIBOOL_HPP_
+
+/*
+
+ <gintenlib/tribool.hpp>
+
+ tribool ¡§ boost::logic::tribool ¤Ø¤Î using Àë¸À
+
+ ¥³¥á¥ó¥È¡§
+ ¡¦¥²¡¼¥à¥é¥¤¥Ö¥é¥ê¤Ç°ì¡¹ boost::logic::tribool ¤È¤¹¤ë¤Î¤¬ÌÌÅÝ¤Ê¤Î¤Ç using Àë¸À¡£
+
+*/
+
+#include <boost/logic/tribool.hpp>
+
+namespace gintenlib
+{
+ using boost::logic::tribool;
+ using boost::logic::indeterminate;
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_TRIBOOL_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_TYPE_HPP_
+#define GINTENLIB_INCLUDED_TYPE_HPP_
+
+/*
+
+ <gintenlib/type.hpp>
+
+ type ¡§ boost::type ¤Î using Àë¸À
+
+ Àë¸À¡§
+ using boost::type;
+
+ µ¡Ç½¡§
+ boost::type ¤Ø¤Î typedef ¤Ç¤¹¡£¼ç¤Ë¡Ö·¿¤Ø¤Î¥·¥ó¥Ü¥ë¡×¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£
+ ¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤Á¤ç¤Ã¤ÈÊ£»¨¤Ê¤³¤È¤ä¤í¤¦¤È¤¹¤ë¤ÈɬÍס£¤è¤¯»È¤¦¤Î¤Ç boost:: ¤ò»È¤ï¤º¤ËºÑ¤à¤è¤¦¡£
+
+*/
+
+#include <boost/type.hpp>
+
+namespace gintenlib
+{
+ using boost::type;
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_INCLUDED_TYPE_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_TYPED_SAVER_HPP_
+#define GINTENLIB_INCLUDED_TYPED_SAVER_HPP_
+
+/*
+
+ <gintenlib/typed_saver.hpp>
+
+ typed_saver ¡§ ¥Ç¥¹¥È¥é¥¯¥¿¤Ç¤ÎÃͤÎÉüµ¢¡Ê¥Æ¥ó¥×¥ì¡¼¥ÈÈÇ¡Ë
+
+ Àë¸À¡§
+ template< typename T >
+ class typed_saver : boost::noncopyable
+ {
+ public:
+ // ÉáÄ̤Υ³¥ó¥¹¥È¥é¥¯¥¿
+ explicit typed_saver( T& t );
+ // t ¤ÎÃͤòÂàÈò¤·¤Æ¤«¤é t1 ¤Ë½ñ¤´¹¤¨¤ë
+ typed_saver( T& t, const T& t1 );
+
+ ~typed_saver();
+
+ // ¤³¤ì¤ò¸Æ¤Ö¤È¡¢¥Ç¥¹¥È¥é¥¯¥¿¤ÇÃͤ¬Ìᤵ¤ì¤ë¤³¤È¤Ï¤Ê¤¯¤Ê¤ë
+ void release();
+
+ // ÌÀ¼¨Åª¤ÊÉüµ¢¡ÊÄ̾ï¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤ÇÉüµ¢¤µ¤ì¤ë¤Î¤Ç½ñ¤¯É¬Íפʤ·¡Ë
+ void restore();
+
+ };
+
+ µ¡Ç½¡§
+ ¥³¥ó¥¹¥È¥é¥¯¥¿¤Ç¼õ¤±¼è¤Ã¤¿ÊÑ¿ô¤ÎÃͤòµÏ¿¤·¡¢¥Ç¥¹¥È¥é¥¯¥¿¤Ç½ñ¤Ìᤷ¤Þ¤¹¡£
+ value_saver ¤È°ã¤¤ÊÑ¿ô¤Î·¿¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¤¬¡¢¤½¤Îʬ¹â®¤ËÆ°ºî¤·¤Þ¤¹¡£
+
+ ¥Ç¥¹¥È¥é¥¯¥¿Á°¤Ç¤â restore() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤»¤Ð¡¢¶¯À©Åª¤Ë½ñ¤Ì᤹¤³¤È¤¬²Äǽ¤Ç¤¹¡£
+ ¤½¤Î»þ¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤Ç¤ÎÃͤνñ¤Ìᤷ¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+ ¤Þ¤¿¥Ç¥¹¥È¥é¥¯¥¿¤Ç¤Î½ñ¤Ìᤷ¤òÍÞÀ©¤·¤¿¤¤¤È¤¤Ï¡¢ release() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤»¤Ð OK ¤Ç¤¹¡£
+
+ Êä»ö¹à¡§
+ typed_saver, value_saver ¤òÍøÍѤǤ¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¾ò·ï¤Ï¡¢
+ ¡Ö¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤«½ê͸¢°ÜÆ°¥³¥ó¥¹¥È¥é¥¯¥¿¤ò»ý¤Ã¤Æ¤¤¤ë¡×¡Ö swap ²Äǽ¡×¤ÎÆóÅÀ¤Ç¤¹¡£
+ ¤Ê¤Î¤Ç¡¢¤Á¤ã¤ó¤È¤·¤¿ swap ¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð std::auto_ptr Åù¤ÎÊѧ¥¯¥é¥¹¤Ç¤âÍøÍѤǤ¤Þ¤¹¡£
+
+*/
+
+#include <algorithm>
+
+#include <boost/noncopyable.hpp>
+#include <boost/utility/addressof.hpp>
+
+namespace gintenlib
+{
+ // ¥³¥ó¥¹¥È¥é¥¯¥¿¤Î»þ¤ÎÃͤˡ¢¥Ç¥¹¥È¥é¥¯¥¿¤Ç¶¯À©Éüµ¢¤µ¤»¤ë¥ª¥Ö¥¸¥§¥¯¥È
+ template< typename T >
+ class typed_saver
+ : boost::noncopyable
+ {
+ public:
+ // t ¤ÎÃͤòµÏ¿¤·¡¢¥Ç¥¹¥È¥é¥¯¥¿¤Ç´¬¤Ì᤹
+ explicit typed_saver( T& t )
+ : target_( boost::addressof(t) ), saver_(t) {}
+
+ // t ¤ÎÃͤòµÏ¿¤·¤Æ¤«¤é¡¢t1 ¤ËÊѹ¹¡¢¥Ç¥¹¥È¥é¥¯¥¿¤ÇÌ᤹
+ typed_saver( T& t, const T& t1 )
+ : target_( boost::addressof(t) ), saver_(t)
+ {
+ t = t1;
+ }
+
+
+ // Éüµ¢
+ ~typed_saver()
+ {
+ restore();
+ }
+
+ // Éüµ¢½èÍý¤ÎÍÞÀ©
+ void release()
+ {
+ target_ = 0;
+ }
+
+ // ÌÀ¼¨Åª¤ÊÉüµ¢¡ÊÄ̾ï¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤ÇÉüµ¢¤µ¤ì¤ë¤Î¤Ç½ñ¤¯É¬Íפʤ·¡Ë
+ void restore()
+ {
+ if( target_ )
+ {
+ using std::swap;
+ swap( *target_, saver_ );
+ target_ = 0;
+ }
+ }
+
+ private:
+ T* target_;
+ T saver_;
+
+ }; // class typed_saver<T>
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_TYPED_SAVER_HPP_
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_VALUE_SAVER_HPP_
+#define GINTENLIB_INCLUDED_VALUE_SAVER_HPP_
+
+/*
+
+ <gintenlib/value_saver.hpp>
+
+ value_saver ¡§ ¥Ç¥¹¥È¥é¥¯¥¿¤Ç¤ÎÃͤÎÉüµ¢
+
+ Àë¸À¡§
+ class value_saver : boost::noncopyable
+ {
+ public:
+ template< typename T > explicit value_saver( T& t );
+ // t ¤ÎÃͤòÂàÈò¤·¤Æ¤«¤é t1 ¤Ë½ñ¤´¹¤¨¤ë
+ template< typename T > value_saver( T& t, const T& t1 );
+
+ ~value_saver();
+
+ // ¤È¤â¤Ë typed_saver ¤ÈƱ¤¸
+ void release();
+ void restore();
+ };
+
+ µ¡Ç½¡§
+ ¥³¥ó¥¹¥È¥é¥¯¥¿¤Ç¼õ¤±¼è¤Ã¤¿ÊÑ¿ô¤ÎÃͤòµÏ¿¤·¡¢¥Ç¥¹¥È¥é¥¯¥¿¤Ç½ñ¤Ìᤷ¤Þ¤¹¡£
+ typed_saver ¤ÏÊÑ¿ô¤Î·¿¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¤¬¹â®¤ËÆ°ºî¤·¡¢
+ value_saver ¤ÏÊÑ¿ô¤Î·¿¤Ë°Í¤é¤Ê¤¤Æ°ºî¤ò¤·¤Þ¤¹¤¬Èæ³ÓŪÄ㮤Ǥ¹¡£
+
+ ¤É¤Á¤é¤â¡¢release() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤Ç¥Ç¥¹¥È¥é¥¯¥¿¤Ç¤Î½ñ¤Ìᤷ¤òÍÞÀ©¤Ç¤¤Þ¤¹¡£
+ ¤Þ¤¿¡¢¥Ç¥¹¥È¥é¥¯¥¿Á°¤Ç¤â restore() ´Ø¿ô¤Ë¤è¤ê¶¯À©Åª¤Ë½ñ¤Ì᤹¤³¤È¤¬²Äǽ¤Ç¤¹¡£
+
+ Êä»ö¹à¡§
+ typed_saver, value_saver ¤òÍøÍѤǤ¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¾ò·ï¤Ï¡¢
+ ¡Ö¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤«½ê͸¢°ÜÆ°¥³¥ó¥¹¥È¥é¥¯¥¿¤ò»ý¤Ã¤Æ¤¤¤ë¡×¡Ö swap ²Äǽ¡×¤ÎÆóÅÀ¤Ç¤¹¡£
+ ¤Ê¤Î¤Ç¡¢¤Á¤ã¤ó¤È¤·¤¿ swap ¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð std::auto_ptr Åù¤ÎÊѧ¥¯¥é¥¹¤Ç¤âÍøÍѤǤ¤Þ¤¹¡£
+
+*/
+
+#include <algorithm>
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/utility/addressof.hpp>
+
+namespace gintenlib
+{
+ // Ëüǽ¥»¡¼¥Ð
+ class value_saver
+ : boost::noncopyable
+ {
+ public:
+ // t ¤ÎÃͤòµÏ¿¤·¡¢¥Ç¥¹¥È¥é¥¯¥¿¤Ç´¬¤Ì᤹
+ template< typename T >
+ explicit value_saver( T& t )
+ : p( new holder<T>(t) ) {}
+
+ // t ¤ÎÃͤòµÏ¿¤·¤Æ¤«¤é¡¢t1 ¤ËÊѹ¹¡¢¥Ç¥¹¥È¥é¥¯¥¿¤ÇÌ᤹
+ template< typename T >
+ value_saver( T& t, const T& t1 )
+ : p( new holder<T>(t) )
+ {
+ t = t1;
+ }
+
+
+ // Éüµ¢
+ ~value_saver()
+ {
+ restore();
+ }
+
+ void release()
+ {
+ p.reset();
+ }
+
+ // ÌÀ¼¨Åª¤ÊÉüµ¢¡ÊÄ̾ï¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤ÇÉüµ¢¤µ¤ì¤ë¤Î¤Ç½ñ¤¯É¬Íפʤ·¡Ë
+ void restore()
+ {
+ if(p)
+ {
+ p->restore();
+ p.reset();
+ }
+ }
+
+ private:
+ class basic_holder : boost::noncopyable
+ {
+ public:
+ virtual ~basic_holder(){}
+ virtual void restore() = 0;
+ };
+
+ boost::scoped_ptr<basic_holder> p;
+
+ template< typename T >
+ class holder : public basic_holder
+ {
+ public:
+ holder( T& t )
+ : target_(t), saver_(t) {}
+
+ ~holder(){}
+
+ virtual void restore()
+ {
+ using std::swap;
+ swap( target_, saver_ );
+ }
+
+ private:
+ T& target_;
+ T saver_;
+
+ }; // class holder<T>
+
+ }; // class value_saver
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_VALUE_SAVER_HPP_
--- /dev/null
+#include "../gintenlib/assign.hpp"
+
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/array.hpp>
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+// ¥Æ¥¹¥ÈËÜÂÎ
+int test_main( int argc, char* argv[] )
+{
+ static const int n = 10;
+
+ int a[n];
+ boost::array<int, n> b;
+
+ // a ¤ò¡¢boost::counting_iterator ¤ò»È¤¤ 0 ¡Á 9 ¤ÎÃͤǽé´ü²½
+ gintenlib::assign( a, boost::counting_iterator<int>(0) );
+ // ¥Á¥§¥Ã¥¯
+ for( int i = 0; i < n; ++i )
+ {
+ BOOST_CHECK( a[i] == i );
+ }
+
+ // b ¤òµÕ½ç¤Ë a ¤Ç½é´ü²½
+ gintenlib::assign( b.rbegin(), b.rend(), &a[0] );
+ // ¥Á¥§¥Ã¥¯
+ for( int i = 0, j = n - 1; i < n; ++i, --j )
+ {
+ BOOST_CHECK( b[i] == a[j] );
+ }
+
+ return 0;
+}
--- /dev/null
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#include "../gintenlib/bool_comparable.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+// ¤Þ¤ºÉáÄ̤Υ¯¥é¥¹¤È¤·¤Æ bool_comparable.hpp Ãæ¤ÎÎãʸ
+
+#include <boost/scoped_ptr.hpp>
+
+template<typename T>
+class my_optional
+ : public gintenlib::bool_comparable< my_optional<T> > // ¤³¤Î¤è¤¦¤Ë»È¤¦
+{
+ // ËÜÂÎÉôʬ¤Ï¤Ê¤ó¤éµ¤¤Ë¤»¤º½ñ¤¤¤Æ¤è¤¤
+ public:
+ typedef T value_type;
+
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ my_optional() : p() {}
+ my_optional( const T& x ) : p( new T(x) ) {}
+
+ reference operator*() { return *p; }
+ const_reference operator*() const { return *p; }
+
+ // operator!() ¤ò³Î¼Â¤Ë¼ÂÁõ¤¹¤ë¤³¤È¤ò˺¤ì¤Ê¤±¤ì¤Ð¡£
+ bool operator!() const { return !p; }
+ // ¤³¤ì¤Ë¤è¤ê¡¢boolÈæ³Ó¤â½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ë
+
+ // ¤Á¤Ê¤ß¤Ë operator!() ¤¸¤ã¤Ê¤¯¤Æ
+ // bool boolean_test() const { return p.get(); }
+ // ¤³¤ì¤Ç¤â¤¤¤¤¡Ê¤½¤Î¾ì¹ç¡¢operator! ¤Ï¼«Æ°ÄêµÁ¡Ë
+
+ // ¤½¤Î¤Û¤«¡¢¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿¤È¤«ÂåÆþ±é»»»Ò¤È¤«¤ÏÌÌÅݤÀ¤«¤é¾Êά
+
+ private:
+ // ÌÌÅݤʥݥ¤¥ó¥¿´ÉÍý¤È¤«¤·¤¿¤¯¤Ê¤¤¤Î¤Ç scoped_ptr ¤ò»È¤¦
+ boost::scoped_ptr<T> p;
+
+};
+
+// ¥Æ¥¹¥È¥±¡¼¥¹
+void my_optional_test()
+{
+ my_optional<int> a, b(1), c(0);
+
+ // ´ðËÜŪ¤Ê¥Á¥§¥Ã¥¯
+
+ // if ¤Î¾ò·ïÉô¤ËľÀܻȤ¦
+ if( a ) { BOOST_ERROR( "a is empty." ); }
+ if( b ); else { BOOST_ERROR( "b is not empty." ); }
+ // ÅöÁ³¤À¤±¤É ! ±é»»»Ò¤â¥Æ¥¹¥È¤¹¤ë
+ if( !c ) { BOOST_ERROR( "c is not empty." ); }
+
+ // || ¤ä &&
+ // || ¤ä && ¤ÏľÀÜ¿½ÅÄêµÁ¤·¤Æ¤Ê¤¤¤Î¤Ç¡¢short circuit ¤Ë¤Ê¤ë¤Ï¤º
+ BOOST_CHECK( b || a );
+ BOOST_CHECK( b && c );
+
+ // 0 ¤È¤ÎÈæ³Ó
+ BOOST_CHECK( a == 0 );
+ BOOST_CHECK( 0 == a ); // µÕ¤â¥Æ¥¹¥È
+ BOOST_CHECK( b != 0 ); // !=
+ BOOST_CHECK( 0 != c ); // != ¤ÎµÕ
+
+ // true, false ¤È¤ÎÈæ³Ó
+ BOOST_CHECK( b == true ); // ¤³¤ì¤Ï£Ï£Ë
+ BOOST_CHECK( false == a ); // £Ï£Ë
+ BOOST_CHECK( c != false ); // £Ï£Ë
+ BOOST_CHECK( true != a ); // £Ï£Ë
+ // BOOST_CHECK( b == 1 ); // ¥³¥ì¤Ï¥À¥á
+
+ // bool ¤Ø¤Î¥¥ã¥¹¥È
+ BOOST_CHECK( static_cast<bool>(a) != static_cast<bool>(b) );
+
+ // ľÀÜÈæ³Ó¤Ï¥À¥á
+ // BOOST_CHECK( a != b );
+ // if( b == c ){ BOOST_ERROR( "1 equals to 0 !?" ); }
+}
+
+
+// ¼¡¡¢Èæ³Ó¤â½ÐÍè¤ë¥¯¥é¥¹
+#include <boost/operators.hpp>
+#include <string>
+using namespace std;
+
+struct eq_cmp
+ : gintenlib::bool_comparable<eq_cmp>,
+ private boost::equality_comparable<eq_cmp>
+{
+ string value;
+ eq_cmp( string x = "" ) : value(x) {}
+
+ // ¤³¤ì¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð£Ï£Ë
+ bool operator!() const { return value.empty(); }
+
+ // equal_to
+ friend bool operator==( const eq_cmp& lhs, const eq_cmp& rhs )
+ {
+ return lhs.value == rhs.value;
+ }
+
+ // ¥Æ¥¹¥È¥³¡¼¥É
+ static void test()
+ {
+ eq_cmp x, y("hoge");
+
+ // ¤³¤ÎÊÕ¤ÏŬÅö¤Ëή¤¹
+ BOOST_CHECK( !x );
+ BOOST_CHECK( y );
+
+ BOOST_CHECK( x != true );
+ BOOST_CHECK( y == true );
+ BOOST_CHECK( x == 0 );
+ BOOST_CHECK( y != 0 );
+
+ // ÅöÁ³¥À¥á
+ // BOOST_CHECK( x != 1 );
+ // BOOST_CHECK( y == 1 );
+
+ // ¤³¤ì¤é¤ÏÈæ³Ó´Ø¿ô¤òÄêµÁ¤·¤Æ¤ë¤Î¤Ç£Ï£Ë
+ BOOST_CHECK( x == x );
+ BOOST_CHECK( x != y );
+ // °ÅÌÛÊÑ´¹¤Ç¤³¤ì¤â£Ï£Ë
+ BOOST_CHECK( x == string("") );
+ BOOST_CHECK( y != string("") );
+
+ // µÕÊý¸þ¤Ç¤â´ðËܣϣË
+ BOOST_CHECK( ( x == true ) == ( true == x ) );
+ BOOST_CHECK( ( x != true ) == ( true != x ) );
+ BOOST_CHECK( ( x == 0 ) == ( 0 == x ) );
+ BOOST_CHECK( ( x != 0 ) == ( 0 != x ) );
+ BOOST_CHECK( ( x == y ) == ( y == x ) );
+ BOOST_CHECK( string("hoge") != x );
+ BOOST_CHECK( string("hoge") == y );
+
+ // µÕÊý¸þ¤Ç¤âÅöÁ³¥À¥á
+ // BOOST_CHECK( 1 != x );
+ // BOOST_CHECK( 1 == y );
+ }
+
+};
+
+
+// int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¾ì¹ç¡¢¤Á¤ç¤Ã¤ÈÆüì
+
+struct convertible_from_int
+ : gintenlib::bool_comparable<convertible_from_int>,
+ private boost::equality_comparable<convertible_from_int>
+{
+ int value;
+ convertible_from_int( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
+
+ bool operator!() const { return value == 0; }
+
+ // operator== ¤Ë¤è¤ëÈæ³Ó¤¬½ÐÍè¤ë¾ì¹ç
+ friend bool operator==( const convertible_from_int& lhs, const convertible_from_int& rhs )
+ {
+ return lhs.value == rhs.value;
+ }
+
+ static void test()
+ {
+ convertible_from_int x, y = 2;
+ BOOST_CHECK( !x ); // ¤³¤¦¤¤¤¦¤Î¤ÏÉáÄ̤˽ÐÍè¤ë¤¬
+ BOOST_CHECK( y );
+ BOOST_CHECK( x == false );
+ BOOST_CHECK( y == true );
+
+ // BOOST_CHECK( x == 0 ); // ¥³¥ì¤¬¼Â¹Ô¤Ç¤¤Ê¤¤¡ÊÛ£Ëæ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡Ë
+ // BOOST_CHECK( y != 0 ); // ÅöÁ³¤³¤ì¤â¥À¥á
+
+ BOOST_CHECK( y == 2 ); // ¤Ç¤â¥³¥ì¤Ï£Ï£Ë
+ BOOST_CHECK( x != 1 ); // ¥³¥ì¤â£Ï£Ë
+ }
+};
+
+// ¤½¤Î¾ì¹ç¡¢int ¤È¤ÎÈæ³Ó¤òÊ̸ÄÄêµÁ¤·¤Æ¤ä¤ì¤Ð£Ï£Ë
+struct convertible_from_int2
+ : gintenlib::bool_comparable<convertible_from_int2>,
+ private boost::equality_comparable<convertible_from_int2>,
+ private boost::equality_comparable<convertible_from_int2, int>
+{
+ int value;
+ convertible_from_int2( int x = 0 ) : value(x) {} // int ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤¤ë¤È¡¦¡¦¡¦
+
+ // ¤³¤Ã¤½¤ê boolean_test ¤ò»È¤¦¡£Æä˰ÕÌ£¤Ï̵¤¤
+ bool operator!() const { return value == 0; }
+
+ // Ä̾ï¤Î == Èæ³Ó¤Ë²Ã¤¨¤Æ
+ friend bool operator==( const convertible_from_int2& lhs, const convertible_from_int2& rhs )
+ {
+ return lhs.value == rhs.value;
+ }
+ // int ¤È¤ÎÈæ³Ó¤òÌÀ¼¨Åª¤ËÄêµÁ¤µ¤¨¤¹¤ì¤Ð
+ friend bool operator==( const convertible_from_int2& lhs, int rhs )
+ {
+ return lhs.value == rhs;
+ }
+
+ static void test()
+ {
+ convertible_from_int2 x, y = 2;
+
+ BOOST_CHECK( x == 0 ); // ¥³¥ì¤â¼Â¹Ô¤Ç¤¤ë¡ª
+ BOOST_CHECK( y != 0 );
+
+ BOOST_CHECK( y == 2 ); // ÅöÁ³¥³¥ì¤â£Ï£Ë
+ BOOST_CHECK( x != 1 );
+
+ BOOST_CHECK( !x ); // ¤Á¤Ê¤ß¤Ë boolean_test() ¤¬¤¢¤ì¤Ð operator !() ¤âÄêµÁ¤µ¤ì¤ë
+ // º£²ó¤Î¥Æ¥¹¥È¤Ë¤Ï¤¢¤Þ¤ê´Ø·¸¤Ê¤¤¤¬
+ BOOST_CHECK( y );
+ BOOST_CHECK( x == false );
+ BOOST_CHECK( y == true );
+ }
+};
+
+
+// ¥Æ¥¹¥È¥á¥¤¥ó
+int test_main( int argc, char* argv[] )
+{
+ my_optional_test();
+ eq_cmp::test();
+ convertible_from_int::test();
+ convertible_from_int2::test();
+
+ return 0;
+}
--- /dev/null
+#include "../gintenlib/clonable_ptr.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+template<typename T>
+void test1( const gintenlib::clonable_ptr<T>& p0 )
+{
+ typedef gintenlib::clonable_ptr<T> ptr_type;
+
+ // ¥Ç¥Õ¥©¥ë¥È¹½ÃÛ
+ {
+ ptr_type p1;
+ // NULL ¤Ë¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë¤«¡©
+ BOOST_CHECK( p1.get() == 0 );
+ }
+
+ // ¥³¥Ô¡¼
+ {
+ // ¥³¥Ô¡¼¤ËÀèΩ¤Ã¤Æ»²¾È¥«¥¦¥ó¥È¤òÄ´¤Ù¤ë
+ int count = p0.use_count();
+
+ // ¥³¥Ô¡¼¤¹¤ë
+ ptr_type p1 = p0;
+ // ¥¢¥É¥ì¥¹¤È»²¾È¥«¥¦¥ó¥È¤ÎξÌ̤ÇÅù¤·¤¤¤³¤È¤ò³Îǧ
+ BOOST_CHECK( p0 == p1 );
+ BOOST_CHECK( p0.use_count() == p1.use_count() );
+
+ // ¤Þ¤¿¡¢¥³¥Ô¡¼¤¬½ÐÍ褿ʬ¡¢»²¾È¥«¥¦¥ó¥È¤ÏÁý¤¨¤Æ¤¤¤ë¤Ï¤º
+ if( p0 )
+ {
+ BOOST_CHECK( p0.use_count() == count+1 );
+ }
+ else
+ {
+ // NULL ¤Î¾ì¹ç¤Ï»²¾È¥«¥¦¥ó¥È¤Ï¥¼¥í¤Ë¤Ê¤ë
+ BOOST_CHECK( count == 0 );
+ BOOST_CHECK( p0.use_count() == 0 );
+ }
+
+ // ¥ê¥»¥Ã¥È¤Î¥Æ¥¹¥È
+ p1.reset();
+ BOOST_CHECK( p1 == 0 );
+
+ // ¤³¤Î»þÅÀ¤Ç»²¾È¥«¥¦¥ó¥È¤Ï¸µ¤ËÌá¤ë¤Ï¤º
+ BOOST_CHECK( p0.use_count() == count );
+ }
+
+ // ËÜÂê¡£clone ¤Î¥Æ¥¹¥È
+ {
+ ptr_type p1;
+ p1 = p0.clone();
+
+ // ¤Þ¤¿¡¢¥³¥Ô¡¼¤¬½ÐÍ褿ʬ¡¢»²¾È¥«¥¦¥ó¥È¤ÏÁý¤¨¤Æ¤¤¤ë¤Ï¤º
+ if( p0 )
+ {
+ BOOST_CHECK( p0.get() != p1.get() );
+ }
+ else
+ {
+ // NULL ¤Î¾ì¹ç¤Ï p1 ¤â¥¼¥í¤Î¤Ï¤º
+ BOOST_CHECK( !p1 );
+ }
+
+ // À¸¥Ý¥¤¥ó¥¿¤Ç to_unique ¤Î³Îǧ
+ T* p_ = p1.get();
+ // ¤³¤ì¤Þ¤Ç¤Î²áÄø¤Ç p1 ¤Ï null ¤« unique ¤Î¤Ï¤º
+ BOOST_CHECK( !p1 || p1.unique() );
+ // unique ¤Î¤È¤¤Ï to_unique() ¤ò¸Æ¤ó¤Ç¤â²¿¤â¤·¤Ê¤¤¤Ï¤º
+ p1.to_unique();
+ BOOST_CHECK( p_ == p1.get() );
+
+ // ¼¡¤Ë p1 ¤Ë¤Õ¤¿¤¿¤Ó p0 ¤ÎÃͤòÆþ¤ì¤ë
+ p1 = p0;
+ // À¸¥Ý¥¤¥ó¥¿¤ÎÃͤò¹¹¿·
+ p_ = p1.get();
+ // ¤³¤ì¤Ë¤è¤ê¡¢NULL ¤Ç¤¢¤ë¤«¥æ¥Ë¡¼¥¯¤¸¤ã¤Ê¤¤¤«¤Î¾õÂ֤ˤʤä¿
+ BOOST_CHECK( !p1 || !p1.unique() );
+ // unique ¤ò¸Æ¤Ö¤È p0 ¤ÏÊѲ½¤»¤º p1 ¤¬ÊѲ½¤¹¤ë¤Ï¤º
+ p1.to_unique();
+ BOOST_CHECK( p_ == p0.get() );
+ BOOST_CHECK( !p1 || p_ != p1.get() );
+ }
+
+ // ¤ª¤Þ¤±¤Ç to_shared
+ {
+ // Àè¤Ë»²¾È¥«¥¦¥ó¥È¤òÄ´¤Ù¤ë
+ int count = p0.use_count();
+
+ boost::shared_ptr<T> p1 = to_shared( p0 );
+ BOOST_CHECK( p0.get() == p1.get() );
+
+ // shared_ptr ¤¬¥ê¥»¥Ã¥È¤µ¤ì¤¿¾ì¹ç¡¢¤Á¤ã¤ó¤È»²¾È¥«¥¦¥ó¥È¤Ï¸º¤ë¡©
+ p1.reset();
+ BOOST_CHECK( p0.use_count() == count );
+ }
+
+ // ¤ª¤ï¤ê
+}
+
+int test_main( int argc, char* argv[] )
+{
+ test1( gintenlib::clonable_ptr<int>( new int() ) );
+ test1( gintenlib::clonable_ptr<int>() );
+
+ return 0;
+}
--- /dev/null
+// ¥Ø¥Ã¥À
+#include "../gintenlib/deep_ptr.hpp"
+
+// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
+// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+// ½ÐÎÏ¡¢¸«¤Å¤é¤¤¤±¤É²¿¤¬µ¯¤³¤Ã¤Æ¤ë¤«¤Ïʬ¤«¤ë¤è¤Í¡©
+
+#include <iostream>
+using namespace std;
+
+// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+#define PRINT_AND_EXECUTE( expr ) \
+ cout << #expr << ";\n"; expr
+
+#define PRINT_EXPR( expr ) \
+ cout << #expr << " -> " << (expr) << endl
+
+
+// ¥Æ¥¹¥È£±¡¢¤Á¤ã¤ó¤È»È¤¨¤ë¤«Ä´¤Ù¤ë
+
+// »ý¤¿¤»¤ë¥¯¥é¥¹
+struct hoge
+{
+ hoge()
+ {
+ cout << "hoge::hoge();\n";
+ }
+
+ hoge( const hoge& )
+ {
+ cout << "hoge::hoge( const hoge& );\n";
+ }
+
+ ~hoge() throw ()
+ {
+ cout << "hoge::~hoge();\n";
+ }
+
+};
+
+void test_hoge()
+{
+ // ¥³¥ó¥¹¥È¥é¥¯¥¿¤Î¥Á¥§¥Ã¥¯
+ gintenlib::deep_ptr<hoge> p1, p2( new hoge() );
+ gintenlib::deep_ptr<const hoge> p3 = p2;
+
+ // ÂåÆþ¥Á¥§¥Ã¥¯
+ // Ãæ¿È¤ò¥³¥Ô¡¼¤¹¤ë¤Î¤Ç const ¤«¤é¤ÎÂåÆþ¤â½ÐÍè¤ë
+ PRINT_AND_EXECUTE( p2 = p3 );
+
+ // reset ¥Á¥§¥Ã¥¯
+ PRINT_AND_EXECUTE( p1.reset( new hoge() ) );
+ PRINT_AND_EXECUTE( p2.reset() );
+
+ // swap ¤Ç;·×¤Ê¥ª¥Ö¥¸¥§¥¯¥È¤¬ºî¤é¤ì¤Ê¤¤¤³¤È¤ò¥Á¥§¥Ã¥¯
+ PRINT_AND_EXECUTE( swap( p1, p2 ) );
+
+ // shared_ptr ¤Ø¤ÎÊÑ´¹¥Á¥§¥Ã¥¯
+ PRINT_AND_EXECUTE( to_shared( p1 ) );
+ PRINT_AND_EXECUTE( to_shared( p2 ) );
+ PRINT_AND_EXECUTE( to_shared( p3 ) );
+
+ // È´¤±¤ë¤è¡¼
+ cout << "leaving test_hoge().\n";
+}
+
+// pimpl ¤Ç»È¤¦¤È³ä¤ÈÊØÍø¤½¤¦¤À¤¬
+// ¥µ¥ó¥×¥ë¤Ï̤´°À®
+
+int main()
+{
+ test_hoge();
+
+ return 0;
+}
+
--- /dev/null
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#include "../gintenlib/deleter.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+#include <boost/noncopyable.hpp>
+
+// ÉÔ´°Á´·¿¡Ê¸å¤Ç»È¤¦¡Ë
+struct incomplete_type;
+
+// ¥Æ¥¹¥ÈÍѤΥ¯¥é¥¹¡¢
+// À¸¤¤Æ¤¤¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¿ô¤ò¿ô¤¨¤ë
+class test_class
+ : boost::noncopyable
+{
+ static int count_;
+
+ public:
+ test_class() { ++count_; }
+ ~test_class(){ --count_; }
+
+ static int use_count(){ return count_; }
+
+};
+int test_class::count_ = 0;
+
+// ¤Þ¤º deleter & dummy_deleter ¤Î¥Æ¥¹¥È
+void test_deleter()
+{
+ const int count = test_class::use_count();
+
+ test_class* p = new test_class();
+ BOOST_CHECK( test_class::use_count() == count + 1 );
+
+ gintenlib::deleter del;
+
+ // ¥Ç¥ê¡¼¥È¤Ã
+ del( p );
+ BOOST_CHECK( test_class::use_count() == count );
+ p = 0;
+ del( p ); // ¤Ì¤ë¤Ý¤ËÂФ·¤Æ¤Ï²¿¤â¤·¤Ê¤¤
+ BOOST_CHECK( test_class::use_count() == count );
+
+ // ¤½¤Î¤Û¤«¡¢¡Ê°ÕÌ£¤Ï̵¤¤¤±¤É¡Ë¤³¤ì¤ÏÆ°¤¯
+ del( new int() );
+ // ¤³¤ó¤Ê¤Î¤â¥®¥ê¥®¥ê¹çË¡
+ del( static_cast<test_class*>(0) );
+ BOOST_CHECK( test_class::use_count() == count ); // ¥«¥¦¥ó¥ÈÊѲ½¤·¤Æ¤Ê¤¤¤è¡©
+
+ // ¤Ç¤â¤³¤ì¤Ï¥À¥á¡£ÉÔ´°Á´·¿¤Î delete
+ // del( static_cast<incomplete_type*>(0) );
+
+ // ÅöÁ³¤È»×¤¦¤Ç¤·¤ç¡¢¤Ç¤â ¢ ¤³¤ì¤À¤È
+ // delete static_cast<incomplete_type*>(0);
+ // ¥³¥ó¥Ñ¥¤¥ëÄ̤äÁ¤ã¤¦¤ó¤Ç¤¹¤è¡©
+ // ¡¦¡¦¡¦¤Þ¡¼ boost::checked_delete ¤Î¤ª¤«¤²¤Ê¤ó¤Ç¤¹¤¬
+
+ // ¤¸¤ã¡¼ dummy_deleter ¤À¤È¤É¤¦¤Ê¤ë¡©
+ p = new test_class();
+ BOOST_CHECK( test_class::use_count() == count + 1 );
+ // ÌÌÅݤʤΤǤ½¤Î¾ì¤Ç¹½ÃÛ¤¹¤ë
+ gintenlib::dummy_deleter()( p );
+
+ // ¼ÂºÝ¤Ë¤Ïºï½ü¤µ¤ì¤Æ¤Ê¤¤¤Î¤Ç¥«¥¦¥ó¥È¤ÏÊѲ½¤·¤Ê¤¤È¦
+ BOOST_CHECK( test_class::use_count() == count + 1 );
+
+ delete p; p = 0; // »ÅÊý¤Ê¤¤¤Î¤Ç¼êÆ° delete
+
+ // ¤³¤ó¤Ê¥Õ¥¡¥ó¥¯¥¿¤Ë°Ọ̃ͤ뤫¤Ã¤Æ¡©
+ // ¤¢¤ë¤è¡£Î㤨¤Ð boost::shared_ptr ¤ò»È¤¦¾ì¹ç¤È¤«¡£
+ // »²¾È´ÉÍý¤Ë boost::weak_ptr ¤ò»È¤¤¤¿¤¤¤±¤É¡¢¥Ý¥¤¥ó¥¿¤Îºï½ü¤Þ¤Ç¤Ï¤·¤ÆÍߤ·¤¯¤Ê¤¤¡¢
+ // ¤½¤¦¤¤¤¦¤È¤¤Ëµ¤·Ú¤Ë»È¤¨¤ë¤Î¤¬ dummy_deleter ¡£
+ // ¤¤¤Á¤¤¤Á¤½¤Î¾ì¤Ç¡Ö²¿¤â¤·¤Ê¤¤¥Õ¥¡¥ó¥¯¥¿¡×¤òºî¤ë¤è¤êµ¤¤¬Íø¤¤¤Æ¤ë¤Ç¤·¤ç¡©
+}
+
+// ¼¡¡¢ typed_deleter ¤Î¥Æ¥¹¥È
+// ¤Ê¤ó¤È¤Ê¤¯»×¤¤Î©¤Ã¤Æ value_saver ¤Ê¤ó¤Æ»È¤Ã¤Æ¤ß¤ë
+#include "../gintenlib/value_saver.hpp"
+
+void test_typed_deleter()
+{
+ using gintenlib::value_saver;
+
+ int i = 1;
+
+ // value_saver ¤òºî¤ë¡£
+ // µ¡Ç½¤Ï¡¢¥Ç¥¹¥È¥é¥¯¥¿¸Æ¤Ó½Ð¤·»þ¤ËÂоÝÊÑ¿ô¤ÎÃͤòÉü¸µ
+ value_saver* p = new value_saver(i);
+
+ BOOST_CHECK( i == 1 );
+ i = 2;
+ BOOST_CHECK( i == 2 );
+
+ gintenlib::typed_deleter<value_saver> del;
+ // ºï½ü¤Ã
+ del( p ); p = 0;
+
+ // ¤³¤ì¤Ë¤è¤ê´¬¤Ìá¤Ã¤¿¤Ï¤º
+ BOOST_CHECK( i == 1 );
+
+ // ¤Þ¡¼¤ä¤Ã¤Æ¤ë¤³¤È¤Ï deleter ¤ÈÊѤï¤ê¤Þ¤»¤ó¡£
+ // del( new int() );
+ // ¤³¤ì¤¬Æ°¤«¤Ê¤¤¤¯¤é¤¤¤Ç¡£
+
+ // typed_dummy_deleter ¤âƱÍͤË
+ p = new value_saver(i);
+ i = 2;
+ BOOST_CHECK( i == 2 );
+ gintenlib::typed_dummy_deleter<value_saver>()( p );
+ // ¥À¥ß¡¼¤Ê¤Î¤ÇÊѤï¤é¤Ê¤¤
+ BOOST_CHECK( i == 2 );
+
+ // ¤á¤ó¤É¤¤¤Î¤Ç delete ¤â¤·¤Ê¤¤¡Ê¤©¤£¡Ë
+}
+
+int test_main( int argc, char* argv[] )
+{
+ test_deleter();
+ test_typed_deleter();
+
+ return 0;
+}
--- /dev/null
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#include <gintenlib/preprocessor/enable_if.hpp>
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+// ¥Æ¥¹¥È¤Ë»È¤¦¥¯¥é¥¹
+struct base {};
+struct derived : base {};
+
+// ¥Æ¥¹¥È¤Ë»È¤¦¥á¥¿´Ø¿ô
+#include <boost/type_traits/is_base_of.hpp>
+
+// GINTENLIB_ENABLE_IF ¤Î¥Á¥§¥Ã¥¯
+// ¤³¤ì¤µ¤¨Ä̤ì¤Ð¡¢¤³¤ÎÆâÉô¤Ç»È¤ï¤ì¤Æ¤¤¤ë
+// <gintenlib/enable_if.hpp>
+// <gintenlib/d_enable_if.hpp>
+// <gintenlib/preprocessor/dequote.hpp>
+// ¤³¤ì¤é¤Î¥Á¥§¥Ã¥¯¤â¼«Æ°Åª¤ËÄ̤俤³¤È¤Ë¤Ê¤ë
+template<typename T>
+bool hoge( const T&, GINTENLIB_ENABLE_IF(( boost::is_base_of<base, T> )) )
+{
+ return true;
+}
+template<typename T>
+bool hoge( const T&, GINTENLIB_DISABLE_IF(( boost::is_base_of<base, T> )) )
+{
+ return false;
+}
+
+
+// ñÂΥƥ¹¥ÈËÜÂÎ
+int test_main( int argc, char* argv[] )
+{
+ derived d;
+ int i;
+
+ BOOST_CHECK( hoge(d) );
+ BOOST_CHECK( !hoge(i) );
+
+ return 0;
+}
--- /dev/null
+#include "../gintenlib/factorize.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+#include <vector>
+#include <iterator>
+using namespace std;
+
+// ¥Á¥§¥Ã¥¯ÍÑ´Ø¿ô
+template<typename T, size_t N>
+inline void check( T x, const T (&ans)[N] )
+{
+ // ¤È¤ê¤¢¤¨¤º¥³¥ó¥Æ¥Ê¤òÍÑ°Õ
+ vector<T> v;
+ // ºÇ½é¤Ë v ¤ÎÎΰè¤ò³ÎÊݤ·¤Æ¤ª¤¯¡Ê factorize ¼ºÇÔ¸å¤Î¥Æ¥¹¥È¤ÇÎΰè°ãÈ¿¤·¤Ê¤¤¤¿¤á¡Ë
+ v.reserve(N);
+
+ // ËÜÂÎ
+ gintenlib::factorize( x, back_inserter(v) );
+
+ // Í×ÁÇ¿ô¤Î¥Á¥§¥Ã¥¯
+ BOOST_CHECK( v.size() == N );
+
+ // ³Æ°ø¿ô¤Î¥Á¥§¥Ã¥¯
+ for( size_t i = 0; i < N; ++i )
+ {
+ BOOST_CHECK( v[i] == ans[i] );
+ }
+}
+
+int test_main( int argc, char* argv[] )
+{
+ // 12 * 23 * 42 = 11592 = 2 * 2 * 2 * 3 * 3 * 7 * 23 ¤ò°ø¿ôʬ²ò
+ {
+ int ans[] = { 2, 2, 2, 3, 3, 7, 23 };
+ check( 12 * 23 * 42, ans );
+ }
+
+ // 8191¡ÊÁÇ¿ô¡Ë ¤ò°ø¿ôʬ²ò
+ {
+ int ans[] = { 8191 };
+ check( 8191, ans );
+ }
+
+ // 1024 = 2 ** 10 ¤ò°ø¿ôʬ²ò
+ {
+ int ans[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
+ check( 1024, ans );
+ }
+
+ // ¤ª¤ï¤ê
+ return 0;
+}
--- /dev/null
+#include "../gintenlib/list_format.hpp"
+#include "../gintenlib/to_string.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+#include <sstream>
+#include <vector>
+
+using namespace std;
+
+int test_main( int argc, char* argv[] )
+{
+ // ¤È¤ê¤¢¤¨¤º¥Ç¡¼¥¿¤òÍÑ°Õ¤¹¤ë
+ vector<int> v;
+ v.push_back( 0 );
+ v.push_back( 6 );
+ v.push_back( 1 );
+ v.push_back( 7 );
+
+ {
+ // ¤Á¤ã¤ó¤Èºî¤ì¤Æ¤ë¡©
+ ostringstream oss;
+ oss << gintenlib::list_format( v );
+ BOOST_CHECK( oss.str() == "( 0, 6, 1, 7 )" );
+ BOOST_CHECK( oss.str() == gintenlib::to_str( gintenlib::list_format( v.begin(), v.end() ) ) );
+ }
+ {
+ // ¥¹¥¿¥¤¥ë¤òÊѲ½¤µ¤»¤Æ¤ß¤è¤¦
+ ostringstream oss;
+ oss << gintenlib::list_format( v, "", " ", "" );
+ BOOST_CHECK( oss.str() == "0 6 1 7" );
+ }
+
+ return 0;
+}
--- /dev/null
+#include "../gintenlib/list_formatter.hpp"
+#include "../gintenlib/to_string.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+#include <sstream>
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+// list_format ¤ÈƱ¤¸¤Ç¼ºÎé
+int test_main( int argc, char* argv[] )
+{
+ // ¤È¤ê¤¢¤¨¤º¥Ç¡¼¥¿¤òÍÑ°Õ¤¹¤ë
+ vector<int> v;
+ v.push_back( 0 );
+ v.push_back( 6 );
+ v.push_back( 1 );
+ v.push_back( 7 );
+
+ {
+ ostringstream oss;
+
+ // formatter ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë
+ gintenlib::list_formatter fmt;
+ // ¥³¥ó¥Æ¥Ê¤Ë³ú¤Þ¤»¤Æ½ÐÎÏ
+ oss << fmt( v );
+
+ BOOST_CHECK( oss.str() == "( 0, 6, 1, 7 )" );
+ BOOST_CHECK( oss.str() == gintenlib::to_str( gintenlib::list_format( v.begin(), v.end() ) ) );
+ }
+ {
+ // ¥¹¥¿¥¤¥ë¤òÊѲ½¤µ¤»¤ë¾ì¹ç¤Ë¡¢¾¯¤·³Ú¤Ë¤Ê¤ë
+ ostringstream oss;
+
+ // formatter ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¤È¤¤Ë»ØÄê
+ gintenlib::list_formatter fmt( "", " ", "" );
+ // ½ÐÎÏÉô¤ÏÊѤ¨¤Ê¤¯¤Æ¤¤¤¤
+ oss << fmt( v );
+
+ BOOST_CHECK( oss.str() == "0 6 1 7" );
+
+ // Ê̤Υ¹¥¿¥¤¥ë¤Ç½ÐÎÏ
+ oss.str( string() );
+ // iterator ¤ò»È¤Ã¤Æ¤ß¤ë
+ copy( v.begin(), v.end(), fmt.make_iterator(oss) );
+
+ BOOST_CHECK( oss.str() == "0 6 1 7" );
+ }
+
+ return 0;
+}
--- /dev/null
+#include "../gintenlib/move_ptr.hpp"
+
+// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
+// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+// ¥³¥á¥ó¥È¤â¾¯¤Ê¤¯Èó¾ï¤Ë¸«Æñ¤¤¥Æ¥¹¥È¤Ç¤¹¤¬¡¢
+// ½ÐÎϤȥ½¡¼¥¹¤ò¸«Èæ¤Ù¤Æ²¿¤¬µ¯¤³¤Ã¤Æ¤ë¤«¤òÇÄ°®¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤
+
+struct hoge
+{
+ // virtual implementation model
+ virtual ~hoge() {}
+
+ virtual void foo() = 0;
+
+ // ´Ø¿ô¤ÎÌá¤êÃͤȤ·¤Æ»È¤¦¤³¤È¤¬½ÐÍè¤ë
+ static gintenlib::move_ptr<hoge> create( int i );
+ // static std::auto_ptr<hoge> create( int i );
+
+};
+
+#include <iostream>
+using namespace std;
+
+// Ê̤ÎÎã¡¢ºï½üÍÑ¥Õ¥¡¥ó¥¯¥¿¤òÍÑ°Õ¤¹¤ë
+struct my_deleter
+{
+ my_deleter( int x = 0 ) : i(x) {}
+
+ template<typename T>
+ void operator()( T* ptr )
+ {
+ cout << *this << ": deleting '" << *ptr << "'...\n";
+ delete ptr;
+ }
+
+ friend ostream& operator<< ( ostream& os, const my_deleter& rhs )
+ {
+ os << "my_deleter";
+
+ if( rhs.i > 0 )
+ {
+ os << " No." << rhs.i;
+ }
+
+ return os;
+ }
+
+ int i;
+};
+
+int main()
+{
+ gintenlib::move_ptr<hoge> p1, p2( hoge::create(2) );
+
+ assert( !p1 );
+ assert( p1 == 0 );
+ assert( p2 );
+ assert( p2 != 0 );
+
+ assert( p1 != p2 );
+ assert( !( p1 == p2 ) );
+
+ gintenlib::move_ptr<hoge> p3 = p2;
+
+ assert( !p2 );
+ assert( p3 );
+
+ swap( p1, p3 );
+
+ assert( p1 );
+ assert( !p3 );
+
+ p1->foo();
+ p1.reset();
+
+ // ¼«ºî¥Ç¥ê¡¼¥¿¤ò»È¤Ã¤Æ¤ß¤ë
+ gintenlib::move_ptr< int, my_deleter > p4( new int(4) ), p5( new int(5), my_deleter(2) );
+ p4 = p5;
+ cout << *p4 << endl;
+
+ gintenlib::move_ptr< const int, my_deleter > p6( p4 );
+ p4.reset( new int(4), my_deleter(3) );
+
+ my_deleter del;
+ cout << get_deleter(p4) << endl;
+ delete p4.release( del );
+ cout << del << endl;
+
+ p4 = gintenlib::const_pointer_cast<int>(p6);
+ assert( !p6 );
+
+ cout << "scope out.\n";
+}
+
+// ËÜÍè¤ÏÊÌ¥Õ¥¡¥¤¥ë¤ËÃÖ¤¯¤Ù¤¤Ç¤¹¤¬´Êά¤Î¤¿¤á¡£
+gintenlib::move_ptr<hoge> hoge::create( int i )
+{
+ struct impl : hoge
+ {
+ explicit impl( int x = 0 ) : i(x)
+ {
+ cout << "hoge(" << i << ") is constructed.\n";
+ }
+ ~impl()
+ {
+ cout << "hoge(" << i << ") is destructed.\n";
+ }
+
+ virtual void foo()
+ {
+ cout << "hoge(" << i << ").foo() is called.\n";
+ }
+
+ private:
+ int i;
+ };
+
+ return gintenlib::move_ptr<hoge>( new impl(i) );
+}
--- /dev/null
+#include "../gintenlib/new_.hpp"
+
+// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
+// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+// ¤È¤¤¤¦¤è¤ê¡¢´Êñ¤Ê»È¤¤Æ»¤òÀâÌÀ¤¹¤ëÄøÅ٤Υ³¡¼¥É¡£
+
+#include <iostream>
+using namespace std;
+
+// shared_ptr ¤ò¼õ¤±¼è¤ë´Ø¿ô
+template<typename T>
+void hoge( const boost::shared_ptr<T>& ptr )
+{
+ // ÆâÍƤÏÊ̤ˤɤ¦¤Ç¤â¤è¤í¤·¤¤
+ cout << *ptr << endl;
+}
+
+void test1()
+{
+ // ´ðËÜŪ¤Ê»È¤¤¤«¤¿
+ // shared_ptr ¤ò¼õ¤±¼è¤ë´Ø¿ô¤¬¤¢¤ë¤È¤¹¤ë¡£Î㤨¤Ð¾å¤Î hoge ¤À¡£
+ // ¤³¤Î¼ê¤Î´Ø¿ô¤Ë¡¢¿·¤·¤¯ºî¤Ã¤¿¥ª¥Ö¥¸¥§¥¯¥È¤òÆþ¤ì¤¿¤¤¡£
+
+ // hoge( new int(23) );
+ // ¤³¤¦½ñ¤±¤ì¤Ð¤¤¤¤¤¬¡¢À¸¥Ý¥¤¥ó¥¿¤«¤é shared_ptr ¤Ø¤Î°ÅÌÛÊÑ´¹¤ÏÉÔ²Äǽ¤Ç¤¢¤ë¡£
+
+ // ¤½¤³¤Ç¤³¤¦½ñ¤¡¢ÌÀ¼¨Åª¤ËÊÑ´¹¤·¤ÆÅϤ¹¤³¤È¤È¤Ê¤ë¡£
+ hoge( boost::shared_ptr<int>( new int(23) ) );
+
+ // ¤³¤ì¤Ï·¿Ì¾ int ¤¬Æó²ó»È¤ï¤ì¤Æ¤¤¤Æ¾éŤǤ¢¤ë¡£¤³¤³¤Ç new_ ¤ò»È¤¨¤Ð
+ hoge( gintenlib::new_<int>( 42 ) );
+ // ¤È½ñ¤±¤ë¡£Â¿¤¯¤Î¥×¥í¥°¥é¥Þ¤Ï¡¢¤³¤ì¤ò¼«Á³¤È´¶¤¸¤ë¤Î¤Ç¤Ï¤Ê¤¤¤À¤í¤¦¤«¡£
+
+ // ¤Þ¤¿¡¢¤³¤ì¤ÏÎã³°°ÂÁ´À¤Î´ÑÅÀ¤«¤é¤â½ÅÍפǤ¢¤ë¡£
+ // ¾Ü¤·¤¯¤Ï http://boost.cppll.jp/HEAD/libs/smart_ptr/shared_ptr.htm#BestPractices ¤ò»²¾È¡£
+ // gintenlib::new_ ¤Ï¡¢¤³¤ÎÌäÂê¤òÈó¾ï¤Ë¤¦¤Þ¤¯°·¤¦¤³¤È¤¬½ÐÍè¤ë¡£
+}
+
+// ¤Þ¤¿ gintenlib::new_ ¤Ï¡¢¤½¤ì°Ê³°¤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß¤¹¤ë¤è¤¦¤Ê¥¯¥é¥¹¤ò´Êñ¤ËºîÀ®¤Ç¤¤ë¡£
+// ¤½¤Î°ìÈ֤λȤ¤Æ»¤Ï¡¢boost::enable_shared_from_this ¤ò»È¤¦¾ì¹ç¤À¤í¤¦¡£
+// gintenlib::new_ °Ê³°¤Ç¹½ÃۤǤ¤Ê¤¤¥¯¥é¥¹¤Ï¡¢³Î¼Â¤Ë shared_ptr ¤Ë³ÊǼ¤µ¤ì¤ë¤«¤é¤Ç¤¢¤ë¡£
+// ¤³¤ì¤é¤Ë¤ÏÆó¤Ä¤Î¼ÂÁõË¡¤¬¤¢¤ë¡£½ç¤Ë¸«¤Æ¤ß¤è¤¦¡£
+
+#include <boost/enable_shared_from_this.hpp>
+
+// ¼ÂÁõ£±
+struct force_shared1
+ : boost::enable_shared_from_this<force_shared1>
+{
+ ~force_shared1() throw () {}
+
+ void foo()
+ {
+ cout << "force_shared1::foo();\n";
+ }
+
+ private:
+ // private ¤ËÁ´¤Æ¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤òÃÖ¤¡¢°ìÈ̤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß
+ force_shared1() {}
+ // ¤½¤Î¾å¤Ç gintenlib::new_core_access ¹½Â¤ÂΤò friend ¤Ë»ØÄꤹ¤ë
+ friend class gintenlib::new_core_access;
+
+};
+
+// ¼ÂÁõ£²
+struct force_shared2
+ : boost::enable_shared_from_this<force_shared2>,
+ gintenlib::enable_static_new_<force_shared2> // ¤³¤ì¤ò»ØÄꤹ¤ë
+{
+ ~force_shared2() throw () {}
+
+ // ŬÅö¤Ë¥á¥ó¥Ð¤òÃÖ¤¯
+ void foo();
+ void bar();
+
+ // enable_static_new_<¥¯¥é¥¹Ì¾> ¤«¤é·Ñ¾µ¤µ¤»¤ë¤³¤È¤Ç¡¢
+ // new_ ¤Ë¤è¤ë¹½Ãۤϡ¢¤½¤Î¥¯¥é¥¹¤ÎÀÅŪ´Ø¿ô new_ ¤òÄ̤·¤Æ¹Ô¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ë
+ static boost::shared_ptr<force_shared2> new_()
+ {
+ cout << "force_shared2::new_();\n";
+ return boost::shared_ptr<force_shared2>( new force_shared2() );
+ }
+ // ÅöÁ³Ê£¿ô¤Î new_ ¤òÃÖ¤±¤ë
+ static boost::shared_ptr<force_shared2> new_( int )
+ {
+ cout << "force_shared2::new_( int );\n";
+ return boost::shared_ptr<force_shared2>( new force_shared2() );
+ }
+
+ private:
+ // ƱÍÍ¤Ë private ¤ËÁ´¤Æ¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤òÃÖ¤¡¢°ìÈ̤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß
+ force_shared2() {}
+
+};
+
+// »È¤¤Êý
+void test2()
+{
+ // »È¤¦Ê¬¤Ë¤Ï¤½¤Îº¹¤ò°Õ¼±¤¹¤ë¤³¤È¤Ï¤Ê¤¤¡£
+ boost::shared_ptr<force_shared1> p1 = gintenlib::new_<force_shared1>();
+ p1->foo();
+
+ boost::shared_ptr<force_shared2> p2 = gintenlib::new_<force_shared2>(),
+ p3 = gintenlib::new_<force_shared2>( 0 );
+}
+
+int main()
+{
+ test1();
+ test2();
+
+}
--- /dev/null
+#include "../gintenlib/options.hpp"
+
+// <gintenlib/options/options.hpp> ¤ÎÎãʸ¤ÈƱ¤¸¥³¡¼¥É
+// Boost.Test ¤Ç¤Î¥Á¥§¥Ã¥¯¤Ï¤â¤¦¾¯¡¹¤ªÂÔ¤Á¤ò¡£
+
+// usage: ¥³¥Þ¥ó¥É̾ ¥ª¥×¥·¥ç¥óʸ»úÎó ²òÀϤµ¤»¤¿¤¤°ú¿ô
+// ¤³¤¦µ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ options ¤Î¤Û¤ÜÁ´µ¡Ç½¤ò¥Æ¥¹¥È¤Ç¤¤ëÎã¤Ç¤¹
+#include <gintenlib/options.hpp>
+#include <gintenlib/cast.hpp>
+
+#include <iostream>
+using namespace std;
+
+int main( int argc, char* argv[] )
+{
+ // °ÅÌÛ¥¥ã¥¹¥È
+ using gintenlib::cast;
+
+ try
+ {
+ if( argc < 2 ){ throw gintenlib::option_error("missing 'OPTSTR'"); }
+
+ // argv[1] ¤ÏÆÃÊ̤ʰú¿ô
+ gintenlib::options opt( argv[1], argc, argv );
+ // ¤Ê¤Î¤Ç²òÀϤµ¤»¤Ê¤¤
+ opt.set_optind( 2 );
+
+ for(;;)
+ {
+ // ²òÀϤµ¤»¤ë¡£ ch ¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤Îʸ»ú¤¬Æþ¤ë
+ int ch = opt();
+ if( ch == -1 ){ break; } // -1: ²òÀϽª¤ï¤ê
+
+ switch(ch)
+ {
+ case '?':
+ // ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "unknown option '" << cast<char>( opt.optopt() ) << "' is given. continue...\n";
+ break;
+
+ case ':':
+ // Ʊ¤¸¤¯ ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "option '" << cast<char>( opt.optopt() ) << "'requires argument. continue...\n";
+ break;
+
+ default:
+ // ¥ª¥×¥·¥ç¥ó°ìÈÌ
+ cout << "option '" << cast<char>( ch ) << "' is given.\n";
+
+ // °ú¿ô¤Ï optarg() ¤Ç³ÍÆÀ
+ // °ú¿ô¤¬Ìµ¤¤¾ì¹ç¤Ï string() ¤¬Æþ¤ë
+ if( !opt.optarg().empty() )
+ {
+ cout << " argument: " << opt.optarg() << endl;
+ }
+ break;
+
+ }
+ }
+
+ // ²òÀϽªÎ»¡£Í¾¤Ã¤¿¥ª¥×¥·¥ç¥ó¤Ï argv[opt.optind()] ¡Á argv[argc-1] ¤Ë½¸¤á¤é¤ì¤ë
+ // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó°ú¿ô¤¬È󥪥ץ·¥ç¥ó°ú¿ô¤Î¸å¤Ë¤¢¤ë¾ì¹ç¡¢ argv ¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤ë
+ // ¤³¤ÎÆ°ºî¤òÈò¤±¤¿¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤Î°ú¿ô¤ò '+' ¤Ç»Ï¤á¤ì¤Ð¤è¤¤
+ cout << "\nextra options are:\n";
+ for( int i = opt.optind(); i < argc; ++i )
+ {
+ cout << argv[i] << endl;
+ }
+ }
+ catch( gintenlib::option_error& e )
+ {
+ // ¥ª¥×¥·¥ç¥ó²òÀϤ˼ºÇÔ¤·¤ÆÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ï¤³¤Á¤é¤ËÈô¤Ö
+ cerr << e.what() << endl;
+ cerr << "usage: " << argv[0] << " OPTSTR [OPTIONS]\n";
+
+ return 1;
+ }
+ catch( std::exception& e )
+ {
+ // ¤½¤Î¤Û¤«¤ÎÎã³°
+ cerr << e.what() << endl;
+ return 1;
+ }
+} // main( argc, argv )
--- /dev/null
+#include "../gintenlib/plane/angle.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+namespace plane = gintenlib::plane;
+
+template<typename T>
+T absolute( T x )
+{
+ return x >= 0 ? x : -x;
+}
+
+#include <boost/math/special_functions/hypot.hpp>
+template<typename Real>
+bool nearly_equal( Real a, Real b, Real eps = 1e-5 )
+{
+ using boost::math::hypot;
+ using std::fabs;
+
+ return a == b ? true : absolute( a - b ) / hypot( a, b ) <= eps;
+}
+template<typename Real>
+bool nearly_equal( const plane::basic_angle<Real>& a, const plane::basic_angle<Real>& b, Real eps = 1e-5 )
+{
+ return nearly_equal( a.theta, b.theta, eps );
+}
+
+typedef plane::angle angle_t;
+
+int test_main( int argc, char* argv[] )
+{
+ // neary_equal ¤Î¥Á¥§¥Ã¥¯
+ BOOST_CHECK( !nearly_equal( 0.0, 1.0 ) );
+
+ // ¹½ÃÛ¡Ê°ú¿ô̵¤·¤Ê¤é 0 ¡¢°ú¿ô¤Ï¥é¥¸¥¢¥óñ°Ì¡Ë
+ angle_t a, b( M_PI );
+
+ BOOST_CHECK( a.theta == 0 );
+ BOOST_CHECK( b.theta == M_PI );
+
+ // to_deg ¤Î¥Æ¥¹¥È
+ BOOST_CHECK( nearly_equal( a.to_deg(), 0.0 ) );
+ BOOST_CHECK( nearly_equal( to_deg(b), 180.0 ) ); // ¤³¤¦½ñ¤¯¤³¤È¤â½ÐÍè¤ë
+ // to_rad ¤Î¥Æ¥¹¥È
+ BOOST_CHECK( a.theta == a.to_rad() );
+ BOOST_CHECK( b.theta == to_rad(b) );
+
+ // ¾¡¼ê¤ÊÃͤËÊѹ¹¡¢¤Ä¤¤¤Ç¤Ë radian ´Ø¿ô¤È degree ´Ø¿ô¤â¥Á¥§¥Ã¥¯
+ a = plane::radian( 1.0 ); // 1rad ¢â 57.3¡ë
+ b = plane::degree( 60.0 ); // ¤Ä¤Þ¤ê a < b
+
+ // == ¤Î¥Æ¥¹¥È¡Ê¤Ä¤¤¤Ç¤Ë rad ´Ø¿ô¤ä deg ´Ø¿ô¤â¥Æ¥¹¥È¡Ë
+ BOOST_CHECK( a == a );
+ BOOST_CHECK( b == b );
+ BOOST_CHECK( a == plane::rad( a.to_rad() ) ); // ¤³¤ì¤Ï¤¢¤¿¤ê¤Þ¤¨
+ BOOST_CHECK( plane::deg( 60.0 ) == b ); // ¾å¸«¤ì¤ÐÅö¤¿¤êÁ°
+ // != ¤Î¥Æ¥¹¥È
+ BOOST_CHECK( a != b );
+ // ¤½¤Î¤Û¤«
+ BOOST_CHECK( a < b );
+ BOOST_CHECK( a <= b );
+ BOOST_CHECK( b > a );
+ BOOST_CHECK( b >= a );
+
+ // ²Ã¸º¾è½ü¡ÊÅö¤¿¤êÁ°¤Î»ö¼Â¡Ë
+ // ¤Ê¤ó¤« + ±é»»»Ò¤È += ±é»»»Ò¤ÎµóÆ°¤¬°ã¤¦¤é¤·¤¤¤Î¤Ç nearly Èæ³Ó¤¹¤ë
+ BOOST_CHECK( nearly_equal( (a+b).theta, a.theta + b.theta ) );
+ BOOST_CHECK( nearly_equal( (a-b).theta, a.theta - b.theta ) );
+ BOOST_CHECK( nearly_equal( (-a).theta , -(a.theta) ) );
+ BOOST_CHECK( nearly_equal( (a*2).theta, a.theta * 2 ) );
+ BOOST_CHECK( nearly_equal( (a/2).theta, a.theta / 2 ) );
+ BOOST_CHECK( nearly_equal( a/b , a.theta / b.theta ) ); // Æó¤Ä¤Î³Ñ¤ÎÈæ¤Ï¼Â¿ô
+ BOOST_CHECK( nearly_equal( (a%b).theta, std::fmod( a.theta, b.theta ) ) ); // ¾ê;»»¤Ï fmod
+
+ // normalize
+ b = a + plane::rad( 2*M_PI );
+ a.normalize(); // a ¤òÀµµ¬²½¡Ê¤³¤Î¾ì¹ç¤ÏÆä˰Ọ̵̃¤¤¤±¤É¡Ë
+ b.normalize(); // b ¤âÀµµ¬²½¡£a ¤È b ¤Ï 2¦Ð ¤À¤±°ã¤¦¤Î¤ÇƱ¤¸Ãͤˤʤë¤Ï¤º
+ BOOST_CHECK( -M_PI <= b.theta && b.theta <= M_PI ); // normalize ¤·¤¿ÃͤϤ³¤Î¾ò·ï¤òËþ¤¿¤¹
+ BOOST_CHECK( nearly_equal( a.theta, b.theta ) );
+ // ¤³¤ó¤É¤Ï -2¦Ð ¤À¤±¤º¤é¤·¤ÆºÆÅÙ¤Á¤§¤Ã¤¯
+ b = a - plane::rad( 2*M_PI );
+ // normalize ¤·¤¿ÃͤΤßɬÍפʤ顢¤³¤¦¤â½ñ¤±¤ë¡ÊÊÑ¿ô¤Ë¤Ï±Æ¶Á¤·¤Ê¤¤¡Ë
+ BOOST_CHECK( nearly_equal( normalized(a).theta, normalized(b).theta ) );
+
+ // ¤³¤ÎÊÕ¤Ï unique ¤Ç¤âÁ´¤¯Æ±¤¸¡Ê·ë²Ì¤ÎÃͤÎÈϰϤÀ¤±¤¬°ã¤¦¡Ë
+ b = a + plane::rad( 2*M_PI );
+ a.unique();
+ b.unique();
+ BOOST_CHECK( 0 <= b.theta && b.theta < M_PI * 2 ); // °ã¤¦¤Î¤Ï¤³¤Î¾ò·ï¤À¤±
+ BOOST_CHECK( nearly_equal( a.theta, b.theta ) );
+ b = a - plane::rad( 2*M_PI );
+ BOOST_CHECK( nearly_equal( uniqued(a).theta, uniqued(b).theta ) );
+
+ // ¶³¦¤Ç¤Î¿¶Éñ¤¤
+ // normalize ¤Î¾ì¹ç¡¢Ãͤ¬ ¡ÞM_PI ¤Î»þ¤Ë¡¢Æ±¤¸³ÑÅ٤ˤâ´Ø¤ï¤é¤ºÅù¤·¤¯¤Ê¤¤¾ì¹ç¤¬¤¢¤ë
+ a = plane::rad( -M_PI );
+ b = plane::rad( +M_PI );
+ BOOST_CHECK( !nearly_equal( normalized(a).theta, normalized(b).theta ) );
+ // unique ¤Ê¤é¡¢¤½¤ÎÅÀ¤Ï°Â¿´¡Ê¤¿¤À¤· 2¦Ð ÉÕ¶á¤Ç¡¢¤´¤¯¶Ï¤«¤Êº¹¤¬Â礤ʰ㤤¤Ë¤Ê¤ê¤¨¤ë¤³¤È¤Ï¤¢¤ë¡Ë
+ BOOST_CHECK( nearly_equal( uniqued(a).theta, uniqued(b).theta ) );
+
+ // ¥µ¥¤¥ó¥³¥µ¥¤¥ó¥¿¥ó¥¸¥§¥ó¥È
+ using namespace std;
+ a = plane::deg(45.0);
+ b = plane::deg(60.0);
+ BOOST_CHECK( nearly_equal( a.sin(), sin( a.theta ) ) );
+ BOOST_CHECK( nearly_equal( a.cos(), cos( a.theta ) ) );
+ BOOST_CHECK( nearly_equal( a.tan(), tan( a.theta ) ) );
+
+ // ¤³¤¦½ñ¤¤¤Æ¤â¤¤¤¤¡Ê¤½¤·¤Æ¤½¤Ã¤Á¤Î¤Û¤¦¤¬¼«Á³¡Ë
+ BOOST_CHECK( nearly_equal( sin(b), sin( b.theta ) ) );
+ BOOST_CHECK( nearly_equal( cos(b), cos( b.theta ) ) );
+ BOOST_CHECK( nearly_equal( tan(b), tan( b.theta ) ) );
+
+ // µÕ»°³Ñ´Ø¿ô
+ double x = 0.5, y = 1.0;
+ BOOST_CHECK( nearly_equal( plane::rad( asin(x) ), angle_t::asin(x) ) );
+ BOOST_CHECK( nearly_equal( plane::rad( acos(x) ), angle_t::acos(x) ) );
+ BOOST_CHECK( nearly_equal( plane::rad( atan(x) ), angle_t::atan(x) ) );
+ BOOST_CHECK( nearly_equal( plane::rad( atan2(y,x) ), angle_t::atan2(y,x) ) );
+
+ return 0;
+}
--- /dev/null
+// ¥Ø¥Ã¥À
+#include "../gintenlib/reference_counter.hpp"
+
+// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
+// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+
+#include <iostream>
+using namespace std;
+
+// Ä̾ïÈÇ
+struct fast_ver
+ : gintenlib::reference_counter<fast_ver>
+{
+ fast_ver()
+ {
+ cout << "fast_ver::fast_ver();\n";
+ }
+
+ ~fast_ver() throw ()
+ {
+ cout << "fast_ver::~fast_ver();\n";
+ }
+
+};
+
+// ¿½Å·Ñ¾µÈÇ
+struct base1
+ : gintenlib::reference_counter<base1, true>
+{
+ base1()
+ {
+ cout << "base1::base1();\n";
+ }
+
+ virtual ~base1() throw ()
+ {
+ cout << "base1::~base1();\n";
+ }
+
+};
+struct base2
+ : gintenlib::reference_counter<base2, true>
+{
+ base2()
+ {
+ cout << "base2::base2();\n";
+ }
+
+ virtual ~base2() throw ()
+ {
+ cout << "base2::~base2();\n";
+ }
+
+};
+// Æó¤Ä¤Î¥¯¥é¥¹¤«¤éÇÉÀ¸¤¹¤ë
+// ÉáÄ̤ϤɤäÁ¤Î¥«¥¦¥ó¥È¤ò»È¤Ã¤Æ¤¤¤¤¤«Ê¬¤«¤é¤º¥³¥ó¥Ñ¥¤¥ëÄ̤é¤Ê¤¤
+struct derived
+ : base1, base2
+{
+ derived()
+ {
+ cout << "derived::derived();\n";
+ }
+
+ virtual ~derived() throw ()
+ {
+ cout << "derived::~derived();\n";
+ }
+
+};
+
+// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+#define PRINT_AND_EXECUTE( expr ) \
+ cout << #expr << ";\n"; expr
+
+#define PRINT_EXPR( expr ) \
+ cout << #expr << " -> " << (expr) << endl
+
+#include <boost/intrusive_ptr.hpp>
+
+
+int main()
+{
+ using boost::intrusive_ptr;
+
+ // Ä̾ïÈÇ
+ {
+ intrusive_ptr<fast_ver> p1 = new fast_ver(), p2;
+
+ PRINT_EXPR( p1->use_count() );
+ PRINT_AND_EXECUTE( p2 = p1 );
+ PRINT_EXPR( p1->use_count() );
+ PRINT_AND_EXECUTE( p1.reset() );
+ PRINT_EXPR( p2->use_count() );
+ PRINT_AND_EXECUTE( p2.reset() );
+ }
+
+ // ¿½Å·Ñ¾µÈÇ
+ {
+ intrusive_ptr<derived> p0 = new derived();
+ intrusive_ptr<base1> p1;
+ intrusive_ptr<base2> p2;
+
+ PRINT_EXPR( p0->use_count() );
+ PRINT_AND_EXECUTE( p1 = p0 );
+ PRINT_EXPR( p0->use_count() );
+ PRINT_AND_EXECUTE( p2 = p0 );
+ PRINT_EXPR( p0->use_count() );
+ PRINT_AND_EXECUTE( p0.reset() );
+ PRINT_EXPR( p1->use_count() );
+ PRINT_AND_EXECUTE( p2.reset() );
+ PRINT_EXPR( p1->use_count() );
+
+ cout << "scope out.\n";
+ }
+
+ return 0;
+}
+
--- /dev/null
+// ¥Ø¥Ã¥À
+#include "../gintenlib/to_shared.hpp"
+#include "../gintenlib/intrusive_to_shared.hpp"
+#include "../gintenlib/reference_counter.hpp"
+
+// ²¾¥Æ¥¹¥È¥³¡¼¥É¤Ê¤Î¤Ç
+// boost.test ¤Ï¤Þ¤À»È¤ï¤Ê¤¤¡£
+
+#include <iostream>
+using namespace std;
+
+// ¥Ç¥Ð¥Ã¥°ÍÑ¥Þ¥¯¥í
+#define PRINT_AND_EXECUTE( expr ) \
+ cout << #expr << ";\n"; expr
+
+#define PRINT_EXPR( expr ) \
+ cout << #expr << " -> " << (expr) << endl
+
+// »ý¤¿¤»¤ë¥¯¥é¥¹
+struct hoge
+ : gintenlib::reference_counter<hoge>
+{
+ hoge()
+ {
+ cout << "hoge::hoge();\n";
+ }
+
+ hoge( const hoge& )
+ {
+ cout << "hoge::hoge( const hoge& );\n";
+ }
+
+ ~hoge() throw ()
+ {
+ cout << "hoge::~hoge();\n";
+ }
+
+};
+
+// ÈÆÍÑÈǤϤޤÀ¥Æ¥¹¥È¤·¤Ê¤¤¡£ intrusive, auto ¤ò¥Á¥§¥Ã¥¯
+int main()
+{
+ // intrusive
+ {
+ // pointer ÈÇ
+ PRINT_AND_EXECUTE( gintenlib::intrusive_to_shared( new hoge() ) );
+
+ boost::intrusive_ptr<hoge> p1;
+ PRINT_AND_EXECUTE( p1 = new hoge() );
+
+ boost::shared_ptr<hoge> p2;
+ // to_shared ÊÑ´¹
+ PRINT_AND_EXECUTE( p2 = gintenlib::to_shared(p1) );
+ // ¤Á¤ã¤ó¤ÈƱ¤¸¥ª¥Ö¥¸¥§¥¯¥È¡©
+ PRINT_EXPR( p1.get() == p2.get() );
+ // ¤â¤È¤â¤È¤Î intrusive ¤ò reset ¤·¤Æ¤âÂç¾æÉפ«¥Á¥§¥Ã¥¯
+ PRINT_AND_EXECUTE( p1.reset() );
+
+ // È´¤±¤Þ¤¹
+ cout << "scope out: p1, p2\n";
+ }
+
+ // auto
+ {
+ std::auto_ptr<hoge> p1;
+ PRINT_AND_EXECUTE( p1.reset( new hoge() ) );
+ PRINT_EXPR( p1.get() );
+ boost::shared_ptr<hoge> p2;
+ PRINT_AND_EXECUTE( p2 = gintenlib::to_shared(p1) );
+
+ // ¤Á¤ã¤ó¤È½ê͸¢°ÜÆ°¤Ç¤¤Æ¤¤¤ë¤«¥Á¥§¥Ã¥¯
+ PRINT_EXPR( p1.get() );
+ PRINT_EXPR( p2.get() );
+
+ // ¤ª¤Þ¤±¡£trivial ¤Ê¤ä¤Ä
+ PRINT_AND_EXECUTE( gintenlib::to_shared(p2) );
+
+ // È´¤±¤Þ¤¹
+ cout << "scope out: p1, p2\n";
+ }
+
+ return 0;
+}
+
--- /dev/null
+#include "../gintenlib/value_saver.hpp"
+#include "../gintenlib/typed_saver.hpp"
+
+// boost ¤ÎñÂΥƥ¹¥È¥Õ¥ì¡¼¥à¥ï¡¼¥¯
+#include <boost/test/minimal.hpp>
+
+// ¥Æ¥¹¥ÈËÜÂΤϥƥó¥×¥ì¡¼¥È¤Çµ½Ò
+template<typename T, typename Saver>
+void test( const T& x0, const T& x1 )
+{
+ T x = x0;
+
+ {
+ // ¤È¤ê¤¢¤¨¤º x ¤ÎÃͤò¥Á¥§¥Ã¥¯
+ BOOST_CHECK( x == x0 );
+
+ // Êݸ
+ Saver saver(x);
+ // saver ¤ËÆͤùþ¤ó¤À»þÅÀ¤Ç¤ÏÃͤÏÊѤï¤é¤Ê¤¤
+ BOOST_CHECK( x == x0 );
+
+ // ÃͤòÊѹ¹
+ x = x1;
+ BOOST_CHECK( x == x1 );
+
+ // ¤³¤³¤Ç¸µ¤ËÌá¤ë¤Ï¤º
+ }
+ BOOST_CHECK( x == x0 );
+
+ {
+ // ¤Þ¤¿Êݸ
+ Saver saver(x);
+ // ÃͤòÊѹ¹
+ x = x1;
+ BOOST_CHECK( x == x1 );
+
+ // ÌÀ¼¨Åª¤ÊÃͤÎÉü¸µ
+ saver.restore();
+ // Éü¸µ¤Ç¤¤¿¤«¥Á¥§¥Ã¥¯
+ BOOST_CHECK( x == x0 );
+
+ // restore() ¸å¤Ï¥Ç¥¹¥È¥é¥¯¥¿¤ÇÉü¸µ¤·¤Ê¤¤¡Ê¤¤¤¤¤«°¤¤¤«¤ÏÊ̤Ȥ·¤Æ¡Ë
+ x = x1;
+ }
+ BOOST_CHECK( x == x1 );
+
+ x = x0;
+ {
+ // Êݸ¤ÈƱ»þ¤ËÃͤò½ñ¤´¹¤¨¤ë¡¢¤È¤¤¤¦¤Î¤Ï³ä¤È¤è¤¯¤¢¤ëÆ°ºî¤Ê¤Î¤Ç
+ // ³Ú¤Ç¤¤ë¤è¤¦¤ËÀìÍÑ¥³¥ó¥¹¥È¥é¥¯¥¿¤òÍÑ°Õ¤·¤Æ¤¢¤ê¤Þ¤¹
+ Saver saver( x, x1 );
+ BOOST_CHECK( x == x1 );
+
+ // ¤¤Á¤ó¤ÈÉü¸µ¤Ç¤¤ë¡©
+ }
+ BOOST_CHECK( x == x0 );
+
+ {
+ // Êݸ¤ÈƱ»þ¤ËÃͤò½ñ¤´¹¤¨¤ë¡¢¤È¤¤¤¦¤Î¤Ï³ä¤È¤è¤¯¤¢¤ëÆ°ºî¤Ê¤Î¤Ç
+ // ³Ú¤Ç¤¤ë¤è¤¦¤ËÀìÍÑ¥³¥ó¥¹¥È¥é¥¯¥¿¤òÍÑ°Õ¤·¤Æ¤¢¤ê¤Þ¤¹
+ Saver saver( x, x1 );
+ BOOST_CHECK( x == x1 );
+
+ // release() ¤ò¸Æ¤Ö¤È
+ saver.release();
+ BOOST_CHECK( x == x1 );
+ }
+ // Éü¸µ¤µ¤ì¤Ê¤¤
+ BOOST_CHECK( x == x1 );
+}
+
+template<typename T>
+void test_saver( const T& x0, const T& x1 )
+{
+ // ·¿ÉÕ¤ÈÈÆÍÑ¡¢Î¾Êý¥Æ¥¹¥È
+ test< T, gintenlib::typed_saver<T> >( x0, x1 );
+ test< T, gintenlib::value_saver >( x0, x1 );
+}
+
+#include <complex>
+#include <boost/shared_ptr.hpp>
+
+int test_main( int argc, char* argv[] )
+{
+ // ÁȤ߹þ¤ß·¿
+ test_saver<int>( 0, 1 );
+
+ // ¥æ¡¼¥¶ÄêµÁ·¿¡Ê e.g. std::complex ¡Ë
+ std::complex<double> j( 0, 1 );
+ test_saver< std::complex<double> >( 1.0, j );
+
+ // ¥æ¡¼¥¶ÄêµÁ·¿¤½¤Î¤Ë¡¢boost::shared_ptr
+ boost::shared_ptr<int> p0, p1( new int(0) );
+ test_saver< boost::shared_ptr<int> >( p0, p1 );
+
+ return 0;
+}