OSDN Git Service

first commit.
authorSubaruG <subaru_g@users.sourceforge.jp>
Thu, 21 Jan 2010 07:34:45 +0000 (16:34 +0900)
committerSubaruG <subaru_g@users.sourceforge.jp>
Thu, 21 Jan 2010 07:34:45 +0000 (16:34 +0900)
58 files changed:
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
gintenlib/assign.hpp [new file with mode: 0644]
gintenlib/bool_comparable.hpp [new file with mode: 0644]
gintenlib/call_traits.hpp [new file with mode: 0644]
gintenlib/cast.hpp [new file with mode: 0644]
gintenlib/clonable_ptr.hpp [new file with mode: 0644]
gintenlib/context_error.hpp [new file with mode: 0644]
gintenlib/d_enable_if.hpp [new file with mode: 0644]
gintenlib/deep_ptr.hpp [new file with mode: 0644]
gintenlib/deleter.hpp [new file with mode: 0644]
gintenlib/enable_if.hpp [new file with mode: 0644]
gintenlib/factorize.hpp [new file with mode: 0644]
gintenlib/ignore.hpp [new file with mode: 0644]
gintenlib/intrusive_to_shared.hpp [new file with mode: 0644]
gintenlib/is_same_class.hpp [new file with mode: 0644]
gintenlib/lexical_cast_default.hpp [new file with mode: 0644]
gintenlib/lexical_convert.hpp [new file with mode: 0644]
gintenlib/list_format.hpp [new file with mode: 0644]
gintenlib/list_formatter.hpp [new file with mode: 0644]
gintenlib/math.hpp [new file with mode: 0644]
gintenlib/move_ptr.hpp [new file with mode: 0644]
gintenlib/new_.hpp [new file with mode: 0644]
gintenlib/options.hpp [new file with mode: 0644]
gintenlib/options/exceptions.hpp [new file with mode: 0644]
gintenlib/options/options.hpp [new file with mode: 0644]
gintenlib/plane/angle.hpp [new file with mode: 0644]
gintenlib/plane/fwd.hpp [new file with mode: 0644]
gintenlib/plane/point.hpp [new file with mode: 0644]
gintenlib/plane/quadrangle.hpp [new file with mode: 0644]
gintenlib/plane/rect.hpp [new file with mode: 0644]
gintenlib/plane/vector.hpp [new file with mode: 0644]
gintenlib/preprocessor/dequote.hpp [new file with mode: 0644]
gintenlib/preprocessor/enable_if.hpp [new file with mode: 0644]
gintenlib/reference_counter.hpp [new file with mode: 0644]
gintenlib/shared_ptr.hpp [new file with mode: 0644]
gintenlib/to_shared.hpp [new file with mode: 0644]
gintenlib/to_string.hpp [new file with mode: 0644]
gintenlib/tribool.hpp [new file with mode: 0644]
gintenlib/type.hpp [new file with mode: 0644]
gintenlib/typed_saver.hpp [new file with mode: 0644]
gintenlib/value_saver.hpp [new file with mode: 0644]
tests/assign.cc [new file with mode: 0644]
tests/bool_comparable.cc [new file with mode: 0644]
tests/clonable_ptr.cc [new file with mode: 0644]
tests/deep_ptr.cc [new file with mode: 0644]
tests/deleter.cc [new file with mode: 0644]
tests/enable_if.cc [new file with mode: 0644]
tests/factorize.cc [new file with mode: 0644]
tests/list_format.cc [new file with mode: 0644]
tests/list_formatter.cc [new file with mode: 0644]
tests/move_ptr.cc [new file with mode: 0644]
tests/new_.cc [new file with mode: 0644]
tests/options.cc [new file with mode: 0644]
tests/plane/angle.cc [new file with mode: 0644]
tests/reference_counter.cc [new file with mode: 0644]
tests/to_shared.cc [new file with mode: 0644]
tests/value_saver.cc [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..6534acb
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,50 @@
+¶äÅ·¥é¥¤¥Ö¥é¥ê ¥é¥¤¥»¥ó¥¹ 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
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..c3871da
--- /dev/null
+++ b/README
@@ -0,0 +1,156 @@
+¶äÅ·¥é¥¤¥Ö¥é¥ê¡Ê 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 ½éÈÇ
diff --git a/gintenlib/assign.hpp b/gintenlib/assign.hpp
new file mode 100644 (file)
index 0000000..1f6b1e7
--- /dev/null
@@ -0,0 +1,73 @@
+#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_
diff --git a/gintenlib/bool_comparable.hpp b/gintenlib/bool_comparable.hpp
new file mode 100644 (file)
index 0000000..e258cde
--- /dev/null
@@ -0,0 +1,327 @@
+#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_
diff --git a/gintenlib/call_traits.hpp b/gintenlib/call_traits.hpp
new file mode 100644 (file)
index 0000000..72284ef
--- /dev/null
@@ -0,0 +1,40 @@
+#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_
diff --git a/gintenlib/cast.hpp b/gintenlib/cast.hpp
new file mode 100644 (file)
index 0000000..220b789
--- /dev/null
@@ -0,0 +1,70 @@
+#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_
diff --git a/gintenlib/clonable_ptr.hpp b/gintenlib/clonable_ptr.hpp
new file mode 100644 (file)
index 0000000..036b0a7
--- /dev/null
@@ -0,0 +1,344 @@
+#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_
diff --git a/gintenlib/context_error.hpp b/gintenlib/context_error.hpp
new file mode 100644 (file)
index 0000000..d2503ce
--- /dev/null
@@ -0,0 +1,28 @@
+#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_
diff --git a/gintenlib/d_enable_if.hpp b/gintenlib/d_enable_if.hpp
new file mode 100644 (file)
index 0000000..26f84cc
--- /dev/null
@@ -0,0 +1,76 @@
+#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_
diff --git a/gintenlib/deep_ptr.hpp b/gintenlib/deep_ptr.hpp
new file mode 100644 (file)
index 0000000..8fd88eb
--- /dev/null
@@ -0,0 +1,137 @@
+#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_ 
diff --git a/gintenlib/deleter.hpp b/gintenlib/deleter.hpp
new file mode 100644 (file)
index 0000000..fdbfa08
--- /dev/null
@@ -0,0 +1,70 @@
+#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_
diff --git a/gintenlib/enable_if.hpp b/gintenlib/enable_if.hpp
new file mode 100644 (file)
index 0000000..90fa62c
--- /dev/null
@@ -0,0 +1,36 @@
+#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_
diff --git a/gintenlib/factorize.hpp b/gintenlib/factorize.hpp
new file mode 100644 (file)
index 0000000..bf24346
--- /dev/null
@@ -0,0 +1,102 @@
+#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_
diff --git a/gintenlib/ignore.hpp b/gintenlib/ignore.hpp
new file mode 100644 (file)
index 0000000..af46363
--- /dev/null
@@ -0,0 +1,45 @@
+#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_
diff --git a/gintenlib/intrusive_to_shared.hpp b/gintenlib/intrusive_to_shared.hpp
new file mode 100644 (file)
index 0000000..963a447
--- /dev/null
@@ -0,0 +1,93 @@
+#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_ 
diff --git a/gintenlib/is_same_class.hpp b/gintenlib/is_same_class.hpp
new file mode 100644 (file)
index 0000000..f4cd3c5
--- /dev/null
@@ -0,0 +1,45 @@
+#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_ 
diff --git a/gintenlib/lexical_cast_default.hpp b/gintenlib/lexical_cast_default.hpp
new file mode 100644 (file)
index 0000000..08c5c2b
--- /dev/null
@@ -0,0 +1,76 @@
+#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_
diff --git a/gintenlib/lexical_convert.hpp b/gintenlib/lexical_convert.hpp
new file mode 100644 (file)
index 0000000..82aad24
--- /dev/null
@@ -0,0 +1,73 @@
+#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_
diff --git a/gintenlib/list_format.hpp b/gintenlib/list_format.hpp
new file mode 100644 (file)
index 0000000..ef0b48a
--- /dev/null
@@ -0,0 +1,148 @@
+#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_
diff --git a/gintenlib/list_formatter.hpp b/gintenlib/list_formatter.hpp
new file mode 100644 (file)
index 0000000..6d119d0
--- /dev/null
@@ -0,0 +1,289 @@
+#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_
diff --git a/gintenlib/math.hpp b/gintenlib/math.hpp
new file mode 100644 (file)
index 0000000..deeb476
--- /dev/null
@@ -0,0 +1,84 @@
+#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_
diff --git a/gintenlib/move_ptr.hpp b/gintenlib/move_ptr.hpp
new file mode 100644 (file)
index 0000000..0618e3b
--- /dev/null
@@ -0,0 +1,317 @@
+#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_ 
diff --git a/gintenlib/new_.hpp b/gintenlib/new_.hpp
new file mode 100644 (file)
index 0000000..9288c86
--- /dev/null
@@ -0,0 +1,220 @@
+#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_
diff --git a/gintenlib/options.hpp b/gintenlib/options.hpp
new file mode 100644 (file)
index 0000000..5e6bf74
--- /dev/null
@@ -0,0 +1,15 @@
+#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_
diff --git a/gintenlib/options/exceptions.hpp b/gintenlib/options/exceptions.hpp
new file mode 100644 (file)
index 0000000..fc0c10f
--- /dev/null
@@ -0,0 +1,55 @@
+#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_
diff --git a/gintenlib/options/options.hpp b/gintenlib/options/options.hpp
new file mode 100644 (file)
index 0000000..f6ab626
--- /dev/null
@@ -0,0 +1,487 @@
+#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_
diff --git a/gintenlib/plane/angle.hpp b/gintenlib/plane/angle.hpp
new file mode 100644 (file)
index 0000000..172efec
--- /dev/null
@@ -0,0 +1,277 @@
+#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_
diff --git a/gintenlib/plane/fwd.hpp b/gintenlib/plane/fwd.hpp
new file mode 100644 (file)
index 0000000..ef34a40
--- /dev/null
@@ -0,0 +1,34 @@
+#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_
diff --git a/gintenlib/plane/point.hpp b/gintenlib/plane/point.hpp
new file mode 100644 (file)
index 0000000..09a7f3f
--- /dev/null
@@ -0,0 +1,91 @@
+#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_
diff --git a/gintenlib/plane/quadrangle.hpp b/gintenlib/plane/quadrangle.hpp
new file mode 100644 (file)
index 0000000..bb98495
--- /dev/null
@@ -0,0 +1,273 @@
+#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_
diff --git a/gintenlib/plane/rect.hpp b/gintenlib/plane/rect.hpp
new file mode 100644 (file)
index 0000000..33800fc
--- /dev/null
@@ -0,0 +1,184 @@
+#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_
diff --git a/gintenlib/plane/vector.hpp b/gintenlib/plane/vector.hpp
new file mode 100644 (file)
index 0000000..d8eb332
--- /dev/null
@@ -0,0 +1,260 @@
+#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_
diff --git a/gintenlib/preprocessor/dequote.hpp b/gintenlib/preprocessor/dequote.hpp
new file mode 100644 (file)
index 0000000..4aaf15a
--- /dev/null
@@ -0,0 +1,87 @@
+#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
diff --git a/gintenlib/preprocessor/enable_if.hpp b/gintenlib/preprocessor/enable_if.hpp
new file mode 100644 (file)
index 0000000..194cff7
--- /dev/null
@@ -0,0 +1,87 @@
+#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
diff --git a/gintenlib/reference_counter.hpp b/gintenlib/reference_counter.hpp
new file mode 100644 (file)
index 0000000..2f27223
--- /dev/null
@@ -0,0 +1,209 @@
+#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_
diff --git a/gintenlib/shared_ptr.hpp b/gintenlib/shared_ptr.hpp
new file mode 100644 (file)
index 0000000..3b4b727
--- /dev/null
@@ -0,0 +1,30 @@
+#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_
diff --git a/gintenlib/to_shared.hpp b/gintenlib/to_shared.hpp
new file mode 100644 (file)
index 0000000..0a427c4
--- /dev/null
@@ -0,0 +1,169 @@
+#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_ 
diff --git a/gintenlib/to_string.hpp b/gintenlib/to_string.hpp
new file mode 100644 (file)
index 0000000..245b0aa
--- /dev/null
@@ -0,0 +1,49 @@
+#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_
diff --git a/gintenlib/tribool.hpp b/gintenlib/tribool.hpp
new file mode 100644 (file)
index 0000000..605e326
--- /dev/null
@@ -0,0 +1,25 @@
+#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_
diff --git a/gintenlib/type.hpp b/gintenlib/type.hpp
new file mode 100644 (file)
index 0000000..d4ce330
--- /dev/null
@@ -0,0 +1,28 @@
+#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_
diff --git a/gintenlib/typed_saver.hpp b/gintenlib/typed_saver.hpp
new file mode 100644 (file)
index 0000000..df1dfe7
--- /dev/null
@@ -0,0 +1,101 @@
+#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_
diff --git a/gintenlib/value_saver.hpp b/gintenlib/value_saver.hpp
new file mode 100644 (file)
index 0000000..6c30926
--- /dev/null
@@ -0,0 +1,123 @@
+#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_
diff --git a/tests/assign.cc b/tests/assign.cc
new file mode 100644 (file)
index 0000000..489278d
--- /dev/null
@@ -0,0 +1,34 @@
+#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;
+}
diff --git a/tests/bool_comparable.cc b/tests/bool_comparable.cc
new file mode 100644 (file)
index 0000000..d1c38d1
--- /dev/null
@@ -0,0 +1,231 @@
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#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;
+}
diff --git a/tests/clonable_ptr.cc b/tests/clonable_ptr.cc
new file mode 100644 (file)
index 0000000..2080e35
--- /dev/null
@@ -0,0 +1,107 @@
+#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;
+}
diff --git a/tests/deep_ptr.cc b/tests/deep_ptr.cc
new file mode 100644 (file)
index 0000000..bf84692
--- /dev/null
@@ -0,0 +1,76 @@
+// ¥Ø¥Ã¥À
+#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;
+}
+
diff --git a/tests/deleter.cc b/tests/deleter.cc
new file mode 100644 (file)
index 0000000..b714a28
--- /dev/null
@@ -0,0 +1,123 @@
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#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;
+}
diff --git a/tests/enable_if.cc b/tests/enable_if.cc
new file mode 100644 (file)
index 0000000..db7e486
--- /dev/null
@@ -0,0 +1,42 @@
+// ¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É
+#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;
+}
diff --git a/tests/factorize.cc b/tests/factorize.cc
new file mode 100644 (file)
index 0000000..cd0b4e9
--- /dev/null
@@ -0,0 +1,54 @@
+#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;
+}
diff --git a/tests/list_format.cc b/tests/list_format.cc
new file mode 100644 (file)
index 0000000..d604aa9
--- /dev/null
@@ -0,0 +1,36 @@
+#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;
+}
diff --git a/tests/list_formatter.cc b/tests/list_formatter.cc
new file mode 100644 (file)
index 0000000..bd468fd
--- /dev/null
@@ -0,0 +1,54 @@
+#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;
+}
diff --git a/tests/move_ptr.cc b/tests/move_ptr.cc
new file mode 100644 (file)
index 0000000..33a2f43
--- /dev/null
@@ -0,0 +1,119 @@
+#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) );
+}
diff --git a/tests/new_.cc b/tests/new_.cc
new file mode 100644 (file)
index 0000000..5f205e6
--- /dev/null
@@ -0,0 +1,112 @@
+#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();
+  
+}
diff --git a/tests/options.cc b/tests/options.cc
new file mode 100644 (file)
index 0000000..193d3b3
--- /dev/null
@@ -0,0 +1,84 @@
+#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 )
diff --git a/tests/plane/angle.cc b/tests/plane/angle.cc
new file mode 100644 (file)
index 0000000..2748d49
--- /dev/null
@@ -0,0 +1,125 @@
+#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;
+}
diff --git a/tests/reference_counter.cc b/tests/reference_counter.cc
new file mode 100644 (file)
index 0000000..d56c016
--- /dev/null
@@ -0,0 +1,119 @@
+// ¥Ø¥Ã¥À
+#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;
+}
+
diff --git a/tests/to_shared.cc b/tests/to_shared.cc
new file mode 100644 (file)
index 0000000..bc35090
--- /dev/null
@@ -0,0 +1,84 @@
+// ¥Ø¥Ã¥À
+#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;
+}
+
diff --git a/tests/value_saver.cc b/tests/value_saver.cc
new file mode 100644 (file)
index 0000000..460320b
--- /dev/null
@@ -0,0 +1,97 @@
+#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;
+}