OSDN Git Service

bug fix and optimize
authorSubaruG <subaru_g@users.sourceforge.jp>
Thu, 21 Jan 2010 07:42:29 +0000 (16:42 +0900)
committerSubaruG <subaru_g@users.sourceforge.jp>
Thu, 21 Jan 2010 07:42:29 +0000 (16:42 +0900)
21 files changed:
gintenlib/cast.hpp
gintenlib/clonable_ptr.hpp
gintenlib/destructor.hpp [new file with mode: 0755]
gintenlib/new_.hpp
gintenlib/optional_storage.hpp [new file with mode: 0755]
gintenlib/options/.svn/entries [new file with mode: 0755]
gintenlib/options/.svn/text-base/exceptions.hpp.svn-base [new file with mode: 0755]
gintenlib/options/.svn/text-base/options.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/entries [new file with mode: 0755]
gintenlib/plane/.svn/text-base/angle.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/text-base/fwd.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/text-base/point.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/text-base/quadrangle.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/text-base/rect.hpp.svn-base [new file with mode: 0755]
gintenlib/plane/.svn/text-base/vector.hpp.svn-base [new file with mode: 0755]
gintenlib/pointer_facade.hpp [new file with mode: 0755]
gintenlib/preprocessor/.svn/entries [new file with mode: 0755]
gintenlib/preprocessor/.svn/text-base/dequote.hpp.svn-base [new file with mode: 0755]
gintenlib/preprocessor/.svn/text-base/enable_if.hpp.svn-base [new file with mode: 0755]
gintenlib/storage.hpp [new file with mode: 0755]
gintenlib/to_shared.hpp

index 220b789..1059aa3 100644 (file)
@@ -15,6 +15,8 @@
   µ¡Ç½¡§
     °ÅÌÛÊÑ´¹¤òÌÀ¼¨Åª¤Ë¹Ô¤¦¤¿¤á¤Î¥­¥ã¥¹¥È¤Ç¤¹¡£ cast<void*>( 0 ) ¤Î¤è¤¦¤Ë»È¤¤¤Þ¤¹¡£
     ¼ç¤Ë¿½ÅÄêµÁ¤µ¤ì¤¿´Ø¿ô¤Î¸Æ¤Ó½Ð¤·¤òÀ©¸æ¤¹¤ë¤È¤­¤Ë»È¤¤¤Þ¤¹¡£
+    Boost ¤Ë¤â implicit_cast ¤È¤¤¤¦Æ±µ¡Ç½¤Î¥­¥ã¥¹¥È¤¬¤¢¤ê¤Þ¤¹¤¬¡¢
+    ¤³¤Á¤é¤Î¤Û¤¦¤¬Ê¸»ú¿ô¤¬¾¯¤Ê¤¤¤È¤¤¤¦ÅÀ¤ÇÍøÅÀ¤¬¤¢¤ê¤Þ¤¹¡£
 
   »ÈÍÑÎ㡧
     void hoge( int ){ cout << "int ÈǤǤ¹\n"; }
index 036b0a7..b55afe9 100644 (file)
     template<typename T>
     struct clonable_ptr
     {
-      // ´ðËÜŪ¤Ê¥á¥½¥Ã¥É¤Ï¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤ÈƱ¤¸¤Ê¤Î¤Ç¾Êά
+      typedef T element_type;
+      typedef T value_type;
+      typedef T* pointer;
+      typedef typename boost::add_reference<T>::type reference;
+      
+      // ¥Ç¥Õ¥©¥ë¥È¥³¥ó¥¹¥È¥é¥¯¥¿
+      clonable_ptr();
+      
+      // ¥Ý¥¤¥ó¥¿¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
+      template<typename U>
+      explicit clonable_ptr( U* p );
+      
+      // copy constructor
+      clonable_ptr( const clonable_ptr& src );
+      template<typename U>
+      clonable_ptr( const clonable_ptr<U>& src );
+      
+      // ¥Ç¥¹¥È¥é¥¯¥¿
+      ~clonable_ptr() {}
+      
+      // nothrow swap
+      void swap( clonable_ptr& other );
+      friend void swap( clonable_ptr& one, clonable_ptr& another );
+      
+      // operator=
+      clonable_ptr& operator=( const clonable_ptr& rhs );
+      template<typename U>
+      clonable_ptr& operator=( const clonable_ptr<U>& rhs );
+      
+      // reset
+      void reset();
+      template<typename U>
+      void reset( U* p );
+      
+      
+      // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿´ØÏ¢¤Î¤¢¤ì¤³¤ì
+      T* get() const;
+      friend T* get_pointer( const clonable_ptr& );
+      T* operator->() const;
+      T& operator*() const;
+      
+      operator unspecified_bool_type() const;
+      bool operator!() const;
+      
       
       // »²¾È¥«¥¦¥ó¥È¤Î¿ô¤òÊÖ¤¹
       int use_count() const;
       boost::shared_ptr<T> to_shared() const;
       friend boost::shared_ptr<T> to_shared( const clonable_ptr& target );
       
-      // ¤½¤Î¤Û¤«¡¢xxx_pointer_cast ·Ï¤Î´Ø¿ô¤â¤¢¤ë
     
     };
+    
+    // Èæ³Ó
+    template<typename T1, typename T2>
+    inline bool operator==( const clonable_ptr<T1>&, const clonable_ptr<T2>& );
+    template<typename T1, typename T2>
+    inline bool operator!=( const clonable_ptr<T1>&, const clonable_ptr<T2>& );
+    template<typename T1, typename T2>
+    inline bool operator<( const clonable_ptr<T1>&, const clonable_ptr<T2>& );
+    
+    // pointer casts
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> static_pointer_cast( const clonable_ptr<T2>& src );
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> dynamic_pointer_cast( const clonable_ptr<T2>& src );
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> const_pointer_cast( const clonable_ptr<T2>& src );
 
   µ¡Ç½¡§
     ÂоݤΡֿ¼¤¤¥³¥Ô¡¼¡×¤òÀ¸À®¤Ç¤­¤ë»²¾È¥«¥¦¥ó¥È¼°¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¡£
 
 */
 
-#include <cassert>
-#include <memory>
-#include <algorithm>
+#include "pointer_facade.hpp"
+#include "reference_counter.hpp"
 
 #include <boost/intrusive_ptr.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/type_traits/remove_const.hpp>
-
-#include "shared_ptr.hpp"
-#include "pointer_facade.hpp"
-#include "reference_counter.hpp"
+#include <utility>  // for std::pair
 
 namespace gintenlib
 {
-  // Àè¹ÔÀë¸À
-  template< typename T > struct clonable_ptr;
-  
- // ºÙ¡¹¤È¤·¤¿¼ÂÁõÍѤÎ̾Á°¶õ´Ö
- namespace detail_
- {
-  struct clonable_holder
+  namespace detail_
   {
-    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
+    // ¥«¥¦¥ó¥È¤µ¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È
+    struct clonable_counted_base
+      : reference_counter<clonable_counted_base>
     {
-      clonable_holder temp( p->clone() );
-      return clonable_ptr<T>( temp.get<T>(), temp );
-    }
-    int use_count() const { return p->use_count(); }
+      // virtual destructor
+      virtual ~clonable_counted_base(){}
+      
+      // ËÜÂΡ¢Ê£À½¤òºî¤ë
+      typedef std::pair<clonable_counted_base*, void*> cloned_type;
+      virtual cloned_type clone() const = 0;
+      
+    };  // clonable_counted_base
     
-   private:
-    // ¥Ý¥¤¥ó¥¿ÊÝ»ýµ¡¹½
-    struct holder_base
-      : reference_counter<holder_base>
+    // make_clonable ÍÑ impl
+    template< typename T >
+    struct clonable_counted_impl_obj
+      : clonable_counted_base
     {
-      // ÇÉÀ¸Àè¤Î¥Ç¥¹¥È¥é¥¯¥¿¤Ë p ¤òºï½ü¤·¤Æ¤â¤é¤¦
-      virtual ~holder_base() throw () {}
-      // ¼«¿È¤òÊ£À½¤¹¤ë
-      virtual boost::intrusive_ptr<holder_base> clone() const = 0;
+      // À©ºî
+      explicit clonable_counted_impl_obj( const T& src )
+        : obj(src) {}
       
-      // ¥Ý¥¤¥ó¥¿¤òÆÀ¤ë
-      void* get(){ return p; }
+      // ²òÊü
+      // virtual ~clonable_counted_impl_obj() {}
       
-     protected:
-      holder_base( void* p_ )
-        : p( p_ ) {}
+      // Ê£À½À©ºî
+      typedef typename boost::remove_const<T>::type T_;
+      typedef clonable_counted_impl_obj<T_> impl_type;
+      
+      using clonable_counted_base::cloned_type;
+      virtual cloned_type clone() const
+      {
+        impl_type* pt = new impl_type(obj);
+        return std::make_pair( pt, pt->get() );
+      }
       
-      void* p;
+      // ÊÝ»ý¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ
+      T* get() { return &obj; }
       
-    };  // struct holder_base
+     private:
+      T obj;
+     
+    };  // clonable_counted_impl_obj
     
-    template<typename T>
-    struct holder
-      : holder_base
+    // ¥Ý¥¤¥ó¥¿¤ÇÅϤµ¤ì¤¿¾ì¹ç¤ËÂбþ
+    template< typename T >
+    struct clonable_counted_impl_p
+      : clonable_counted_base
     {
-      explicit holder( T* src ) : holder_base( src ) {}
-      virtual ~holder() throw () { boost::checked_delete( static_cast<T*>(p) ); }
+      explicit clonable_counted_impl_p( T* p_ )
+        : p( p_ ) {}
       
-      // ¿·¤·¤¯³ÎÊݤµ¤ì¤¿¥Ý¥¤¥ó¥¿ src ¤«¤é holder ¤òºî¤ë
-      // ºî¤ë²áÄø¤ÇÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ë¤Ï src ¤ò delete ¤¹¤ë
-      static boost::intrusive_ptr<holder> new_( T* src )
+      // ²òÊü½èÍý
+      virtual ~clonable_counted_impl_p()
       {
-        // Îã³°¤òÅꤲ¤ë²ÄǽÀ­¤¬¤¢¤ë½èÍý¤ÎÁ°¤Ë¡¢¥Ý¥¤¥ó¥¿¤ò 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 );
+        boost::checked_delete(p);
       }
       
-      // holder ¼«¿È¤È¡¢ÊÝ»ý¤µ¤ì¤Æ¤¤¤ë¥Ý¥¤¥ó¥¿¡¢Î¾Êý¤Î¥³¥Ô¡¼¤òºî¤ë
-      virtual boost::intrusive_ptr<holder_base> clone() const
+      // Ê£À½À©ºî
+      using clonable_counted_base::cloned_type;
+      typedef typename boost::remove_const<T>::type T_;
+      typedef clonable_counted_impl_obj<T_> impl_type;
+      virtual cloned_type clone() const
       {
-        return new_( new T( *static_cast<T*>(p) ) );
+        impl_type* pt = new impl_type(*p);
+        return std::make_pair( pt, pt->get() );
       }
       
-    };  // struct holder
+      // ÊÝ»ý¤¹¤ë¥Ý¥¤¥ó¥¿¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ
+      T* get() const { return p; }
+      
+     private:
+      T* p;
     
-    // ¼ÂÁõ¤Î¥Ý¥¤¥ó¥¿
-    boost::intrusive_ptr<holder_base> p;
+    };  // clonable_counted_impl_p
     
-    // ¼ÂÁõÍѤÎ΢¸ý¥³¥ó¥¹¥È¥é¥¯¥¿
-    explicit clonable_holder
-      ( const boost::intrusive_ptr<holder_base>& ptr )
-        : p( ptr ) {}
     
-    // ¼ÂÁõÍѤΥݥ¤¥ó¥¿¼èÆÀ
-    template<typename T>
-    T* get() const
+    // cloning_ptr ÍѤλ²¾È¥«¥¦¥ó¥¿
+    struct clonable_count
     {
-      return static_cast<T*>( p->get() );
-    }
+      // ¥Ç¥Õ¥©¥ë¥È½é´ü²½
+      clonable_count() {}
+      
+      // T ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È p_ ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥«¥¦¥ó¥¿¤òºî¤ë
+      template<typename T>
+      explicit clonable_count( T* p_ )
+        : p( p_ ? new clonable_counted_impl_p<T>(p_) : 0 ) {}
+      
+      // clonable_counted_base* ¤«¤é¤Î¹½ÃÛ
+      clonable_count( clonable_counted_base* p_ )
+        : p( p_ ) {}
+      
+      // ¥Ç¥¹¥È¥é¥¯¥¿¤Ï¼«Æ°ÄêµÁ¤µ¤ì¤¿ÅۤǤª£ë
+      // ~clonable_count(){}
+      
+      // no throw swap
+      void swap( clonable_count& other )
+      {
+        p.swap( other.p );
+      }
+      friend void swap( clonable_count& one, clonable_count& another )
+      {
+        one.swap( another );
+      }
+      
+      // Ê£À½À©ºî
+      typedef std::pair<clonable_count, void*> cloned_type;
+      // clonable_count ¤Ï clonable_counted_base* ¤«¤é°ÅÌÛÊÑ´¹¤Ç¤­¤ë
+      cloned_type clone() const
+      {
+        return p ? cloned_type( p->clone() ) : cloned_type( 0, 0 );
+      }
+      
+      // ÆâÉô¤Î¥«¥¦¥ó¥È¤ò»ÈÍѤ¹¤ë
+      int use_count() const { return p ? p->use_count() : 0; }
+      // ¥æ¥Ë¡¼¥¯¤«Èݤ«
+      bool unique() const { return use_count() == 1; }
+      
+     private:
+      boost::intrusive_ptr<clonable_counted_base> p;
+    
+    };  // clonable_count
     
-  };
+    class clonable_ptr_tag {};
+    
+  } // namespace detail_
   
-  // pointer_facade ÍÑ¥«¥Æ¥´¥ê¥¿¥°
-  struct clonable_ptr_tag {} ;
   
- }  // namespace detail_
   
-  // ËÜÂÎ
-  template< typename T >
+  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;
+   private:
+    typedef clonable_ptr this_type;
+    typedef detail_::clonable_count clonable_count;
     
+   public:
     // ¥Ç¥Õ¥©¥ë¥È¥³¥ó¥¹¥È¥é¥¯¥¿
-    clonable_ptr() : p(0), holder() {}
-
+    clonable_ptr() : p(), count() {}
+    
     // ¥Ý¥¤¥ó¥¿¤«¤éºî¤ë¥³¥ó¥¹¥È¥é¥¯¥¿
-    // Îã³°°ÂÁ´À­¤¬ÌÌÅݤÀ¤¬
     template<typename U>
-    explicit clonable_ptr( U* ptr )
-       : p( ptr ), holder( ptr ) {}
+    explicit clonable_ptr( U* p_ )
+      : p( p_ ), count( p_ ) {}
     
-    // ¥³¥Ô¡¼¥³¥ó¥¹¥È¥é¥¯¥¿
+    // copy constructor ¤Ç¤Ï clone ¤·¤Ê¤¤
     clonable_ptr( const clonable_ptr& src )
-       : p( src.p ), holder( src.holder ) {}
-    template< typename U >
+      : p( src.p ), count( src.count ) {}
+    template<typename U>
     clonable_ptr( const clonable_ptr<U>& src )
-       : p( src.p ), holder( src.holder ) {}
+      : p( src.p ), count( src.count ) {}
     
-    // ¥Ç¥¹¥È¥é¥¯¥¿
-    // ¥á¥ó¥Ð¤¬Å¬Àڤ˽èÍý¤·¤Æ¤¯¤ì¤ë¤¿¤á¡¢ÄêµÁ¤¹¤ëɬÍפʤ·
+    // ¥Ç¥¹¥È¥é¥¯¥¿¤Î½èÍý¤Ï clonable_count ¤ËǤ¤»¤ë
     // ~clonable_ptr() {}
     
-    // nothrow swap ( for operator= )
-    void swap( clonable_ptr& other )
+    // swap
+    void swap( this_type& other )
     {
       using std::swap;
       swap( p, other.p );
-      swap( holder, other.holder );
+      swap( count, other.count );
     }
-    friend void swap( clonable_ptr& one, clonable_ptr& another )
+    friend void swap( this_type& one, this_type& another )
     {
       one.swap( another );
     }
     
-    // ÂåÆþ½èÍý
-    clonable_ptr& operator=( const clonable_ptr& src )
+    // ÂåÆþ±é»»
+    this_type& operator=( const this_type& rhs )
     {
-      clonable_ptr(src).swap( *this );
+      this_type(rhs).swap( *this );
       return *this;
     }
-    template< typename U >
-    clonable_ptr& operator=( const clonable_ptr<U>& src )
+    template<typename U>
+    this_type& operator=( const clonable_ptr<U>& rhs )
     {
-      clonable_ptr(src).swap( *this );
+      this_type(rhs).swap( *this );
       return *this;
     }
     
-    // get pointer
-    // ¤³¤ì¤µ¤¨ÄêµÁ¤¹¤ì¤Ð¸å¤Ï pointer_facade ¤Ë¤è¤ê¼«Æ°ÄêµÁ¤µ¤ì¤ë
-    T* get() const { return p; }
-    
+    // reset
     void reset()
-    {
-      clonable_ptr().swap( *this );
+    { 
+      this_type().swap( *this );
     }
     template<typename U>
-    void reset( U* ptr )
-    {
-      clonable_ptr(ptr).swap( *this );
+    void reset( U* p_ )
+    { 
+      this_type(p_).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
+    // get() ¤µ¤¨ÄêµÁ¤¹¤ì¤Ð¸å¤Ï pointer_facade ¤Ë¤è¤ê¼«Æ°
+    T* get() const { return p; }
+    
+    
+    // ËÜÂÎ
+    
+    // Ê£À½À©ºî
+    typedef typename boost::remove_const<T>::type T_;
+    typedef clonable_ptr<T_> cloned_type;
+    cloned_type clone() const
     {
-      // NULL ¤Ê¤é¤Ê¤Ë¤â¤·¤Ê¤¤  
-      if( !p ){ return clonable_ptr<object_type>(); }
-      
-      // holder ¤ËÍê¤ë
-      return holder.make_clone<object_type>();
+      return cloned_type( count.clone() );
     }
-    // ¼«¿È¤¬Â¾¤Î¥Ý¥¤¥ó¥¿¤È»²¾ÈÀè¤ò¶¦Í­¤·¤Æ¤¤¤ë¤È¤­¡¢
-    // ¼«¿È¤òÊ£À½¤¹¤ë¤³¤È¤Ç¡¢»²¾ÈÀ褬ͣ°ì¤Î¸ºß¤È¤Ê¤ë¤è¤¦¤Ë¤¹¤ë
+    // »²¾È¥«¥¦¥ó¥È·×»»
+    int use_count() const { return count.use_count(); }
+    bool unique() const { return count.unique(); }
+    // unique ¤¸¤ã¤Ê¤±¤ì¤ÐÊ£À½¤·¤Æ unique ¤Ë
     void to_unique()
     {
-      // NULL ¤Ê¤é¤Ê¤Ë¤â¤·¤Ê¤¤  
-      if( !p ){ return; }
-      
-      // ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
-      if( !unique() )
+      if( p != 0 && !unique() )
       {
-        clonable_ptr( this->clone() ).swap( *this );
+        clone().swap(*this);
       }
     }
     
-    // to_shared ´Ø¿ô´ØÏ¢
-    
-    // Êä½õ¥Õ¥¡¥ó¥¯¥¿
-    struct deleter_for_to_shared
+    // to_shared
+    struct to_shared_helper
     {
-      explicit deleter_for_to_shared( const clonable_ptr& src )
-        : p(src) {}
-      clonable_ptr p;
+      to_shared_helper( const clonable_count& count_ )
+        : count( count_ ) {}
       
-      // operator() ¤Ï²¿¤â¤·¤Ê¤¤
-      void operator()( T* p_ )
-      {
-        // ¤¤¤ä¡¢assert ¤À¤±¤«¤±¤ë
-        using namespace std;
-        assert( p.get() == p_ );
-      }
+      // ¥Ç¥¹¥È¥é¥¯¥¿¤ÇŬµ¹¤ä¤Ã¤Æ¤¯¤ì¤ë¤Î¤Ç
+      // operator() ¤Ç¤Ï²¿¤â¹Ô¤ï¤Ê¤¤
+      void operator()( T* ) const {}
       
-    };  // struct deleter_for_to_shared
-    
-    // shared_ptr ¤Ø¤ÎÊÑ´¹
-    shared_ptr<T> to_shared() const
+     private:
+      clonable_count count;
+      
+    };
+    // shared_ptr ¤ËÊÑ´¹
+    boost::shared_ptr<T> to_shared() const
     {
-      if( p )
-      {
-        return shared_ptr<T>( p, deleter_for_to_shared(*this) );
-      }
-      else
-      {
-        return shared_ptr<T>();
-      }
+      return p ? boost::shared_ptr<T>( p, to_shared_helper(count) ) : boost::shared_ptr<T>();
     }
-    // friend ´Ø¿ôÈÇ
-    friend boost::shared_ptr<T> to_shared( const clonable_ptr& target )
+    friend boost::shared_ptr<T> to_shared( const this_type& 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;
+    clonable_count count;
     
-    // make_clone ¤«¤é¸Æ¤Ó½Ð¤¹¤¿¤á¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
-    clonable_ptr( T* ptr, const holder_type& h )
-      : p(ptr), holder(h) {}
-  
-  };  // class clonable_ptr<T>
+    template<typename U> friend class clonable_ptr;
+    
+    clonable_ptr( const clonable_count& count_, T* p_ )
+      : p(p_), count(count_) {}
+    explicit clonable_ptr( const clonable_count::cloned_type& pair )
+      : p( static_cast<T*>( pair.second ) ), count( pair.first ) {}
+    
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> static_pointer_cast( const clonable_ptr<T2>& src );
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> dynamic_pointer_cast( const clonable_ptr<T2>& src );
+    template<typename T1, typename T2>
+    friend clonable_ptr<T1> const_pointer_cast( const clonable_ptr<T2>& src );
+    
+  };  // clonable_ptr<T>
   
   // pointer casts
-  template<typename Target, typename Source>
-  inline clonable_ptr<Target> static_pointer_cast( const clonable_ptr<Source>& t )
+  template<typename T, typename S>
+  inline clonable_ptr<T> static_pointer_cast( const clonable_ptr<S>& src )
   {
-    // ¤ß¤¿¤Þ¤ó¤Þ¡£¥Û¥ë¥À¡¼¤Ï¶¦ÍѤ¹¤ë
-    return clonable_ptr<Target>( static_cast<Target*>( t.p ), t.holder );
+    return clonable_ptr<T>( src.count, static_cast<T*>(src.p) );
   }
-  template<typename Target, typename Source>
-  inline clonable_ptr<Target> dynamic_pointer_cast( const clonable_ptr<Source>& t )
+  template<typename T, typename S>
+  inline clonable_ptr<T> dynamic_pointer_cast( const clonable_ptr<S>& src )
   {
-    // dynamic_cast ¤Î¾ì¹ç¡¢¥­¥ã¥¹¥È¤·¤¿·ë²Ì NULL ¤Ë¤Ê¤ë¤³¤È¤¬¤¢¤ë
-    Target* ptr = dynamic_cast<Target*>( t.p );
-    return ptr ? clonable_ptr<Target>( ptr, t.holder ) : clonable_ptr<Target>();
+    T* p = dynamic_cast<T*>(src.p);
+    return p ? clonable_ptr<T>( src.count, p ) : clonable_ptr<T>();
   }
-  template<typename Target, typename Source>
-  inline clonable_ptr<Target> const_pointer_cast( const clonable_ptr<Source>& t )
+  template<typename T, typename S>
+  inline clonable_ptr<T> const_pointer_cast( const clonable_ptr<S>& src )
   {
-    return clonable_ptr<Target>( const_cast<Target*>( t.p ), t.holder );
+    return clonable_ptr<T>( src.count, const_cast<T*>(src.p) );
   }
-  
-}   // namespace gintenlib
+
+} // namespace gintenlib
 
 #endif  // #ifndef GINTENLIB_INCLUDED_CLONABLE_PTR_HPP_
diff --git a/gintenlib/destructor.hpp b/gintenlib/destructor.hpp
new file mode 100755 (executable)
index 0000000..54b4c9d
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef GINTENLIB_INCLUDED_DESTRUCTOR_HPP_
+#define GINTENLIB_INCLUDED_DESTRUCTOR_HPP_
+
+/*
+
+      <gintenlib/destructor.hpp>
+
+  destructor ¡§ ¥Ç¥¹¥È¥é¥¯¥¿¸Æ¤Ó½Ð¤·¤ÈÅù²Á¤Ê¥Õ¥¡¥ó¥¯¥¿
+  typed_destructor ¡§ ·¿¤Î»ØÄꤵ¤ì¤¿ destructor
+
+  µ¡Ç½¡§
+    ¥Ç¥¹¥È¥é¥¯¥¿¸Æ¤Ó½Ð¤·ÍѤδؿô¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡£¤½¤ì°Ê³°¤Î²¿Êª¤Ç¤â¤¢¤ê¤Þ¤»¤ó¡£
+    deleter ¤Ï boost::checked_delete ¤ò¸Æ¤ó¤Ç¤Þ¤¹¤¬¡¢¤³¤ÎÃæ¤Ç¤Ïñ¤Ë delete ±é»»»Ò¤ò¸Æ¤ó¤Ç¤¤¤ë¤À¤±¡£
+    dummy_deleter ¤Ï delete ±é»»»Ò¤¹¤é¸Æ¤Ð¤Ê¤¤¡¢Ã±¤Ê¤ë¥×¥ì¡¼¥¹¥Û¥ë¥À¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£
+    ¤½¤ì¤¾¤ì·¿ÉեС¼¥¸¥ç¥ó¤â¤¢¤ê¡¢¤½¤ì¤é¤Ï unary_function ¤Î¾ò·ï¤òËþ¤¿¤·¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include <functional>
+#include <boost/checked_delete.hpp>
+
+namespace gintenlib
+{
+  // ¥Ç¥¹¥È¥é¥¯¥¿¤ò¸Æ¤Ó½Ð¤¹¥Õ¥¡¥ó¥¯¥¿
+  struct destructor
+  {
+    typedef void result_type;
+    
+    template<typename T>
+    void operator()( T* p ) const
+    {
+      p->~T();
+    }
+    
+  };  // struct destructor
+  
+  // ·¿¤Î«Çû¤µ¤ì¤¿ destructor
+  template<typename T>
+  struct typed_destructor
+    : std::unary_function<T*, void>
+  {
+    void operator()( T* p ) const
+    {
+      destructor().operator()<T>( p );
+    }
+  
+  };  // struct typed_destructor<T>
+
+}   // namespace gintenlib
+
+#endif  // #ifndef GINTENLIB_INCLUDED_DESTRUCTOR_HPP_
index 9288c86..990ed69 100644 (file)
     // ¤Û¤«¤Ë¡¢new_ ¤ÈƱ¤¸µ¡Ç½¤ò»ý¤Ã¤¿¥Õ¥¡¥ó¥¯¥¿¡¢ new_ptr<T> ¤¬Â¸ºß¤¹¤ë¡£
 
   µ¡Ç½¡§
-    T ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò new ±é»»»Ò¤ÇÀ½ºî¤·¡¢¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ë³ÊǼ¤·¤ÆÊÖ¤¹´Ø¿ô¡£
-    ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Î·¿¤Ï ptr<T>::type ¤ÇÄ´¤Ù¤ë¤³¤È¤¬½ÐÍè¤ë¡£¤³¤Î·¿¤Ï boost::shared_ptr<T> ¤ËÅù¤·¤¤¡£
-    ¤³¤Î´Ø¿ô¤«¤é¤Î new ¥¢¥¯¥»¥¹¤Ï¡¢Á´¤Æ new_core_access ¹½Â¤ÂΤòÄ̤·¤Æ¹Ô¤ï¤ì¤ë¡£¤è¤Ã¤Æ
+     T ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò new ±é»»»Ò¤ÇÀ½ºî¤·¡¢boost::shared_ptr<T> ¤Ë³ÊǼ¤·¤ÆÊÖ¤¹´Ø¿ô¡£
+    ´ðËÜŪ¤ÊÆ°ºî¤Ï boost::make_shared ¤ÈÁ´¤¯Æ±ÍͤǤ¢¤ë¤¬¡¢´ö¤Ä¤«¤Î°ã¤¤¤¬¤¢¤ë¡£
+    ¤³¤Î´Ø¿ô¤«¤é¤Î 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 ¤ËÌÀ¼¨ÅªÊÑ´¹¤¹¤ë¤³¤È¤µ¤¨½ÐÍè¤ì¤ÐǤ°Õ¤Ç¤¢¤ë¡£
+    ¤ÈÀë¸À¤·¤¿¾å¤Ç¥³¥ó¥¹¥È¥é¥¯¥¿¤ò private Éôʬ¤Ë¤ª¤±¤Ð¡¢new_ °Ê³°¤«¤é¤Î¹½ÃÛ¤ò¶Ø»ß½ÐÍè¤ë¡£
+    ¤â¤· private ¥³¥ó¥¹¥È¥é¥¯¥¿¤ÎÁ´¤Æ¤ò¸ø³«¤¹¤ë¤Î¤¬·ù¤Ê¾ì¹ç¤Ï¡¢
+     enable_static_new_ ¥Æ¥ó¥×¥ì¡¼¥È¥¯¥é¥¹¤ò»È¤¦¤³¤È¤Ç¡¢¸Æ¤Ó½Ð¤·¤ò¥«¥¹¥¿¥Þ¥¤¥º¤Ç¤­¤ë¡£
+     ¤½¤Î¾ì¹ç¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤ÎÂå¤ï¤ê¤Ë new_ ¤È¤¤¤¦Ì¾Á°¤ÎÀÅŪ´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£
     
   »ÈÍÑÎ㡧
     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 ¤¬Æ°¤«¤Ê¤¤¤È¤É¤¦¤·¤è¤¦¤â¤Ê¤¤¡¢¤È¤¤¤¦¥Ç¥á¥ê¥Ã¥È¤â¤¢¤ê¤Þ¤¹¡£
-    Æä˺Ǹå¤Î¥¢¥¯¥»¥¹À©¸Â¤ò¹Ô¤¦¾ì¹ç¤Ë¤Ï¡¢¤½¤ì¤é¤Î¥Ç¥á¥ê¥Ã¥È¤â¹Íθ¤·¤¿¾å¤Ç¿µ½Å¤Ë·è¤á¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£
+    ´ðËÜŪ¤ÊÍøÅÀ¤Ï boost::make_shared ¤ÈƱ¤¸¤Ç¤¹¡£
+    ¤¹¤Ê¤ï¤ÁÎã³°°ÂÁ´À­¤Î¶¯²½¤È¼Â¹Ô®Å٤κÇŬ²½¤ò´üÂԤǤ­¤Þ¤¹¡£
+    ¤³¤Î new_ ¥é¥¤¥Ö¥é¥ê¤Ï¡¢¤½¤ì¤Ë²Ã¤¨¡¢¥¢¥¯¥»¥¹À©¸Â¤ò¹Ô¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+    ¤³¤ì¤Ë¤è¤ê¡¢ enable_shared_from_this ¤ò»È¤Ã¤¿¥¯¥é¥¹¤Ê¤É¡Ö³Î¼Â¤Ë shared_ptr ¤ËÆþ¤ì¤¿¤¤¡×
+    ¥¯¥é¥¹¤ò°·¤¦¾ì¹ç¤Î°ÂÁ´À­¤¬¾å¾º¤·¤Þ¤¹¡£
+    ¤È¤Ï¤¤¤¨¡¢°ìÈ̤ˤϥ¹¥¿¥Ã¥¯¤Ë¤âÃÖ¤±¤¿Êý¤¬¤¤¤¤¤Î¤Ç¡¢»È¤¤¤É¤³¤í¤Ï¹Í¤¨¤Þ¤·¤ç¤¦¡£
     
   È÷¹Í¡§
     °ú¿ô¤Ï const& ¤ÇÅϤµ¤ì¤Þ¤¹¡£Èóconst»²¾È¤òÅϤ·¤¿¤¤¾ì¹ç¤Ë¤Ï boost::ref ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£
 
 #include "shared_ptr.hpp"
 #include "enable_if.hpp"
-#include <boost/preprocessor.hpp>
+#include "optional_storage.hpp"
+
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
 #include <boost/type_traits/is_base_of.hpp>
 
 // °ú¿ô¤ÎºÇÂçÃÍ
@@ -101,17 +101,18 @@ namespace gintenlib
     friend class new_ptr;
     
     // Ä̾ï¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤ò¸Æ¤Ó½Ð¤¹ new
+    // placement 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 ) ) \
-      {   \
+    #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 ) ) );  \
       }
     
@@ -119,6 +120,27 @@ namespace gintenlib
     
     #undef GINTENLIB_GEN
     
+    
+    // placement new ¤ò¸Æ¤Ó½Ð¤¹
+    template<typename T>
+    static T* placement_new( void* p )
+    {
+      return ::new (p) T();
+    }
+    // Â¿°ú¿ôÈÇ
+    #define GINTENLIB_GEN( z, n, d )                                  \
+      template< typename T, BOOST_PP_ENUM_PARAMS( n, typename A ) >   \
+      static T* placement_new                                         \
+        ( void* p, BOOST_PP_ENUM_BINARY_PARAMS( n, const A, &arg ) )  \
+      {                                                               \
+        return ::new (p) 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()
@@ -126,12 +148,13 @@ namespace gintenlib
       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 ) ) );  \
+    #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, _ )
@@ -151,24 +174,74 @@ namespace gintenlib
   {
     typedef typename ptr<T>::type result_type;
     
+    // <boost/make_shared.hpp> ¤Ë½¬¤¤¡¢¸úΨŪ¤Ê¼ÂÁõ¤ò¹Ô¤¦
     result_type operator()() const
     {
-      return new_core_access::template normal_new<T>();
+      // ²¾¤Î shared_ptr ¤òºî¤Ã¤Æ»²¾È¥«¥¦¥ó¥È¤òºîÀ®¤·
+      shared_ptr<T> pt( static_cast<T*>(0), deleter() );
+      // »²¾È¥«¥¦¥ó¥ÈÆâ¤Î¥Ç¥ê¡¼¥¿¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ¤¹¤ë
+      optional_storage<T> &storage = boost::get_deleter<deleter>(pt)->storage;
+      void* pv = storage.address();
+      
+      // ¥Ç¥ê¡¼¥¿Æâ¤ËÍÑ°Õ¤µ¤ì¤¿Îΰè¤Ë¥ª¥Ö¥¸¥§¥¯¥È¤ò¹½ÃÛ¤·¡¢
+      T* pt2 = new_core_access::template placement_new<T>( pv );
+      storage.set_initialized();
+      
+      // ¹½ÃÛ¤µ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¢¥É¥ì¥¹¤ÈºÇ½é¤Ëºî¤Ã¤¿»²¾È¥«¥¦¥ó¥È¤«¤é¡¢
+      // ²þ¤á¤Æ shared_ptr ¤òÀ©ºî¤¹¤ë
+      return make_result( pt, pt2 );
     }
     // Â¿°ú¿ôÈÇ
-    #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 ) ); \
+    #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 \
+      {                                                           \
+        shared_ptr<T> pt( static_cast<T*>(0), deleter() );        \
+        optional_storage<T> &storage =                            \
+          boost::get_deleter<deleter>(pt)->storage;               \
+        void* pv = storage.address();                             \
+                                                                  \
+        T* pt2 = new_core_access::template placement_new<T>       \
+          ( pv, BOOST_PP_ENUM_PARAMS( n, arg ) );                 \
+        storage.set_initialized();                                \
+                                                                  \
+        return make_result( pt, pt2 );                            \
       }
     
     BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(GINTENLIB_ARG_COUNT), GINTENLIB_GEN, _ )
     
     #undef GINTENLIB_GEN
-  };
+    
+   private:
+    // ¥«¥¹¥¿¥à¥Ç¥ê¡¼¥¿
+    struct deleter
+    {
+      deleter(){}
+      // ¥³¥Ô¡¼¤Ç¤Ï²¿¤â¤·¤Ê¤¤¤è¤¦ºÇŬ²½
+      deleter( const deleter& ) {}
+      
+      // ¥ª¥Ö¥¸¥§¥¯¥È¤¬³ÊǼ¤µ¤ì¤ëÎΰè
+      optional_storage<T> storage;
+      
+      typedef void result_type;
+      void operator()( T* p )
+      {
+        storage.destory();
+      }
+      
+    };  // struct deleter
+    
+    // ½ªÎ»½èÍý
+    result_type make_result( const result_type& pt, T* pt2 ) const
+    {
+      // enable_shared_from_this ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢Àµ¤·¤¯¥¢¥É¥ì¥¹¤òÀßÄꤹ¤ëɬÍפ¬¤¢¤ë
+      boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
+      // ¤³¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï pt ¤Î»²¾È¥«¥¦¥ó¥È¤È pt2 ¤Î¥¢¥É¥ì¥¹¤ò»È¤Ã¤Æ shared_ptr ¤òºî¤ë
+      return result_type( pt, pt2 );
+    }
+    
+  };  // struct new_ptr<T>
   
   // ´Ø¿ô¥ª¥Ö¥¸¥§¥¯¥ÈÈÇ new_¡ÊÀÅŪ´Ø¿ôÈÇ¡Ë
   template<typename T>
@@ -181,13 +254,13 @@ namespace gintenlib
       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 ) ); \
+    #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, _ )
@@ -203,11 +276,12 @@ namespace gintenlib
     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 ) );  \
+  #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, _ )
diff --git a/gintenlib/optional_storage.hpp b/gintenlib/optional_storage.hpp
new file mode 100755 (executable)
index 0000000..ffc0e51
--- /dev/null
@@ -0,0 +1,181 @@
+#ifndef GINTENLIB_INCLUDED_OPTIONAL_STORAGE_HPP_
+#define GINTENLIB_INCLUDED_OPTIONAL_STORAGE_HPP_
+
+/*
+
+      <gintenlib/optional_storage.hpp>
+
+  optional_storage ¡§ ¸å¤«¤é½é´ü²½¤Ç¤­¤ë¥á¥â¥êÎΰè
+
+  Àë¸À¡§
+    template<typename T>
+    struct optional_storage
+      : private boost::noncopyable
+    {
+      typedef T element_type;
+      typedef T value_type;
+      
+      // ¹½ÃÛ¡¿ÇË´þ
+      optional_storage();
+      ~optional_storage() throw ();
+      
+      // Ãæ¤Î¥Ç¡¼¥¿¤òÇË´þ¤¹¤ë
+      void destory();
+      // ¥«¥¹¥¿¥à¥Ç¥¹¥È¥é¥¯¥¿¤ò»È¤Ã¤Æ¥Ç¡¼¥¿¤òÇË´þ¤¹¤ë
+      template<typename Destructor>
+      void destory( Destructor d );
+      
+      // storage ¤ÎÀ¸¥¢¥É¥ì¥¹¤òÆÀ¤ë
+      void* address();
+      const void* address() const;
+      
+      // ½é´ü²½¤º¤ß¤«Èݤ«
+      bool initialized() const;
+      // ½é´ü²½¤º¤ß¥Þ¡¼¥¯¤ò¤Ä¤±¤ë
+      void set_initialized();
+      
+      // ¹½ÃۺѤߤʤ顢¹½ÃÛ¤µ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ¤¹¤ë
+      T* get();
+      const T* get() const;
+      // ¥¢¥í¡¼±é»»
+      T* operator->();
+      const T* operator->() const;
+      // »²¾È³°¤·
+      T& operator*();
+      const T& operator*() const;
+      
+    };  // optional_storage<T>
+
+  µ¡Ç½¡§
+    Í½¤á¥á¥â¥êÎΰè¤ò³ÎÊݤ·¤Æ±¾¡¹¡¢¤È¤¤¤¦¡¢¾¯¤·±ø¤¤½èÍý¤ò¹Ô¤¤¤¿¤¤¾ì¹ç¤Ã¤Æ¤Î¤¬»þ¡¹¤¢¤ê¤Þ¤¹¡£
+    ¤½¤¦¤¤¤¦¤È¤­¤Ë¡¢¤¢¤ëÄøÅٰ¿´¤·¤Æ½èÍý¤ò¹Ô¤¨¤ë¤è¤¦¤Ë¤¹¤ë°Ù¤Î¥¯¥é¥¹¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤¹¡£
+    Í½¤á¥á¥â¥êÎΰè¤ò³ÎÊݤ·¤Æ²¿¤«¤·¤é¤Î½èÍý¤ò¤·¤Æ¤«¤é¡¢ address() ¤Ç̤½é´ü²½¥á¥â¥ê¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ¡£
+    ¤½¤Î¥¢¥É¥ì¥¹¤Ë placement new ¤Ç¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤Ã¤¿¤é set_initialized() ¤ò¸Æ¤Ö¡£
+    ¤³¤Î°ìÏ¢¤ÎÆ°ºî¤µ¤¨¹Ô¤¨¤Ð¡¢¸å¤ÎÇË´þ¤ä²¿¤ä¤é¤Ï¡¢Á´¤Æ optional_storage<T> ¤¬¤ä¤Ã¤Æ¤¯¤ì¤Þ¤¹¡£
+    boost::optional<T> ¤Ç¤â»÷¤¿¤è¤¦¤Ê¤³¤È¤Ï½ÐÍè¤Þ¤¹¤¬¡¢Ì¤½é´ü²½¥¢¥É¥ì¥¹¤òľÀÜÆÀ¤é¤ì¤Þ¤»¤ó¡£
+    
+    ¤Þ¤¿¡¢optional_storage<T> ¤ò»È¤Ã¤Æ¹½ÃۺѤߥª¥Ö¥¸¥§¥¯¥È¤òÇË´þ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¢
+    ÉáÄ̤Υǥ¹¥È¥é¥¯¥¿¤À¤±¤Ç¤Ê¤¯¡¢¥«¥¹¥¿¥à¥Ç¥¹¥È¥é¥¯¥¿¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
+    ¤½¤¦¤¤¤¦¾ì¹ç¤ÏÌÀ¼¨Åª¤Ë destory ¤ò¸Æ¤Ó½Ð¤·¡¢¤½¤Î°ú¿ô¤Ë¥«¥¹¥¿¥à¥Ç¥¹¥È¥é¥¯¥¿¤òÅϤ·¤Þ¤·¤ç¤¦¡£
+
+  »ÈÍÑÎ㡧
+    // ¤È¤ê¤¢¤¨¤ºÎΰè¤À¤±³ÎÊݤ·¤Æ
+    gintenlib::optional_storage<hoge> storage;
+    
+    // storage ¤¬É¬Íפʲ¿¤«¤·¤é¤Î½èÍý
+    
+    // placement new ¤Ç¹½ÃÛ
+    ::new ( storage.address() ) hoge( args );
+    // ¹½ÃÛ¤·¤¿¤è¥Þ¡¼¥¯¤ò¤Ä¤±¤ë
+    storage.set_initialized();
+    
+    // ¤á¤ó¤É¤¤¤Î¤Ç»²¾ÈÊÑ¿ô¤Ç°Ê¹ß¤Î¥¢¥¯¥»¥¹¤ò´Êά²½
+    hoge& h = *storage;
+    
+    // °Ê¹ß¡¢ h ¤ÏÉáÄ̤Πhoge ¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ°·¤¨¤ë
+    // storage ¤ÎÍ­¸ú´ü¸Â¤¬ÀÚ¤ì¤ë¤È¡¢¼«Æ°¤Ç¥Ç¥¹¥È¥é¥¯¥È¤µ¤ì¤ë¤Î¤Ç°Â¿´
+
+  Êä­¡§
+    ¡¦placement new ¤ò¸Æ¤ó¤À¤é¡¢Â¨ set_initialized() ¤ò¸Æ¤Ó½Ð¤·¤Þ¤·¤ç¤¦¡£
+    ¡¦¤½¤ì¤µ¤¨¼é¤ì¤Ð¡¢Èó¾ï¤Ë°ÂÁ´À­¤Ï¹â¤¤È¦¤Ç¤¹¡£
+
+*/
+
+#include <cassert>
+#include <boost/noncopyable.hpp>
+
+#include "destructor.hpp"
+#include "storage.hpp"
+
+namespace gintenlib
+{
+  // ¤Á¤ç¤Ã¤È°ÂÁ´À­¤ÎÄ㤤 boost::optional
+  template<typename T>
+  struct optional_storage
+    : private boost::noncopyable
+  {
+    typedef       T     element_type;
+    typedef       T       value_type;
+    typedef       T*         pointer;
+    typedef const T*   const_pointer;
+    typedef       T&       reference;
+    typedef const T& const_reference;
+    
+    // ¹½ÃÛ¡¿ÇË´þ
+    optional_storage()
+      : initialized_( false ) {}
+    
+    ~optional_storage() throw ()
+    {
+      destory();
+    }
+    
+    // Ãæ¤Î¥Ç¡¼¥¿¤òÇË´þ¤¹¤ë
+    void destory()
+    {
+      destory( destructor() );
+    }
+    // ¥«¥¹¥¿¥à¥Ç¥¹¥È¥é¥¯¥¿¤ò»È¤Ã¤Æ¥Ç¡¼¥¿¤òÇË´þ¤¹¤ë
+    template<typename Destructor>
+    void destory( Destructor d )
+    {
+      if( initialized_ )
+      {
+        d( get() );
+        initialized_ = false;
+      }
+    }
+    
+    // storage ¤ÎÀ¸¥¢¥É¥ì¥¹¤òÆÀ¤ë
+    void* address(){ return storage_.address(); }
+    const void* address() const { return storage_.address(); }
+    
+    // ½é´ü²½¤º¤ß¤«Èݤ«
+    bool initialized() const { return initialized_; }
+    
+    // ½é´ü²½¤º¤ß¥Þ¡¼¥¯¤ò¤Ä¤±¤ë
+    void set_initialized() { initialized_ = true; }
+    
+    
+    // ¹½ÃۺѤߤʤ顢¹½ÃÛ¤µ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ¤¹¤ë
+    T* get(){ return initialized() ? static_cast<T*>( address() ) : 0; }
+    const T* get() const { return initialized() ? static_cast<const T*>( address() ) : 0; }
+    
+    // ¥¢¥í¡¼±é»»
+    T* operator->()
+    {
+      using namespace std;
+      assert( initialized() );
+      return get();
+    }
+    const T* operator->() const
+    {
+      using namespace std;
+      assert( initialized() );
+      return get();
+    }
+    // »²¾È³°¤·
+    T& operator*()
+    {
+      using namespace std;
+      assert( initialized() );
+      return *get();
+    }
+    const T& operator*() const
+    {
+      using namespace std;
+      assert( initialized() );
+      return *get();
+    }
+    
+   private:
+    bool initialized_;
+    typedef storage<T> storage_type;
+    storage_type storage_;
+    
+  };  // optional_storage<T>
+
+}   // namespace gintenlib
+
+
+#endif  // #ifndef GINTENLIB_INCLUDED_OPTIONAL_STORAGE_HPP_
diff --git a/gintenlib/options/.svn/entries b/gintenlib/options/.svn/entries
new file mode 100755 (executable)
index 0000000..832efee
--- /dev/null
@@ -0,0 +1,96 @@
+10
+
+dir
+5
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib/trunk/gintenlib/options
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib
+
+
+
+2009-06-11T06:54:59.958975Z
+5
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5afde9dc-4444-11de-aefe-d0e08963c90a
+\f
+options.hpp
+file
+15
+
+
+
+2009-12-09T06:48:02.203125Z
+5f95a30d7bb4bd66c3f157c04f1d6292
+2009-12-09T16:31:05.984915Z
+15
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13481
+\f
+exceptions.hpp
+file
+15
+
+
+
+2009-12-09T05:46:30.031250Z
+e95975b921f964562ee49e72ba010548
+2009-12-09T16:31:05.984915Z
+15
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1506
+\f
diff --git a/gintenlib/options/.svn/text-base/exceptions.hpp.svn-base b/gintenlib/options/.svn/text-base/exceptions.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/options.hpp.svn-base b/gintenlib/options/.svn/text-base/options.hpp.svn-base
new file mode 100755 (executable)
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/.svn/entries b/gintenlib/plane/.svn/entries
new file mode 100755 (executable)
index 0000000..fca7585
--- /dev/null
@@ -0,0 +1,217 @@
+10
+
+dir
+4
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib/trunk/gintenlib/plane
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib
+
+
+
+2009-05-19T10:33:48.631974Z
+3
+ginten
+\f
+point.hpp
+file
+12
+
+
+
+2009-12-08T23:08:04.218750Z
+a24fb67f55f5b2a764b13e652f12ed3f
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2264
+\f
+rect.hpp
+file
+12
+
+
+
+2009-12-08T22:57:39.890625Z
+f5040b1f4a1270989d9eab12067f027b
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4626
+\f
+fwd.hpp
+file
+12
+
+
+
+2009-12-08T22:55:38.343750Z
+019fd4acf95a0291266dfc694bee2172
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+565
+\f
+vector.hpp
+file
+12
+
+
+
+2009-12-08T22:56:21.078125Z
+ff474d2bdb01d24a963f22eae3adb0c2
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6491
+\f
+quadrangle.hpp
+file
+12
+
+
+
+2009-12-08T23:08:58.562500Z
+53ebc6ced04dd4dbe1c87c88871e9272
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7562
+\f
+angle.hpp
+file
+12
+
+
+
+2009-12-08T22:55:24.031250Z
+649b7eff433194b68302e73569549fed
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6725
+\f
diff --git a/gintenlib/plane/.svn/text-base/angle.hpp.svn-base b/gintenlib/plane/.svn/text-base/angle.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/fwd.hpp.svn-base b/gintenlib/plane/.svn/text-base/fwd.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/point.hpp.svn-base b/gintenlib/plane/.svn/text-base/point.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/quadrangle.hpp.svn-base b/gintenlib/plane/.svn/text-base/quadrangle.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/rect.hpp.svn-base b/gintenlib/plane/.svn/text-base/rect.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/vector.hpp.svn-base b/gintenlib/plane/.svn/text-base/vector.hpp.svn-base
new file mode 100755 (executable)
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/pointer_facade.hpp b/gintenlib/pointer_facade.hpp
new file mode 100755 (executable)
index 0000000..4465086
--- /dev/null
@@ -0,0 +1,201 @@
+#ifndef GINTENLIB_INCLUDED_POINTER_FACADE_HPP_
+#define GINTENLIB_INCLUDED_POINTER_FACADE_HPP_
+
+/*
+
+      <gintenlib/pointer_facade.hpp>
+
+  pointer_facade ¡§ ´Ê°×¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿À½ºî
+
+  Àë¸À¡§
+    template< class Derived, typename T, typename Category = Derived >
+    struct pointer_facade
+    {
+      typedef T  element_type;
+      typedef T  value_type;
+      typedef T* pointer;
+      typedef T& reference;
+      
+      // »²¾È³°¤·¤È¥Ý¥¤¥ó¥¿¼èÆÀ
+      reference operator*() const;
+      pointer operator->() const;
+      friend pointer get_pointer( const Derived& target );
+      
+      // bool Èæ³Ó
+      operator unspecified_bool_type() const;
+      bool operator!() const;
+    
+    };
+    
+    // ¥Æ¥ó¥×¥ì¡¼¥ÈÈÇÁê¸ßÈæ³Ó
+    // ¥«¥Æ¥´¥ê¤¬Æ±¤¸¤â¤Î¤Ê¤éÁê¸ßÈæ³Ó£Ï£Ë
+    template<typename T, typename U, typename D1, typename D2, typename C>
+    inline bool operator==
+      ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
+      
+    template<typename T, typename U, typename D1, typename D2, typename C>
+    inline bool operator!=
+      ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
+    
+    template<typename T, typename U, typename D1, typename D2, typename C>
+    inline bool operator<
+      ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs );
+  
+  µ¡Ç½¡§
+    get() ¤µ¤¨¼ÂÁõ¤¹¤ì¤Ð¡¢¤½¤ì¤ò¸µ¤Ë¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤·¤ÆɬÍפʤâ¤Î¤òÀ¸À®¤¹¤ë¥¯¥é¥¹¤Ç¤¹¡£
+    ¼ÂÁõ¤·¤Æ¤¯¤ì¤ë¤â¤Î¤Ï°Ê²¼¤ÎÄ̤ꡧ
+    ¡¡¡¦element_type, value_type, pointer, reference ¤Î·¿ÄêµÁ
+    ¡¡¡¦operator*, operator->, get_pointer() ¤Ë¤è¤ë¥Ý¥¤¥ó¥¿¼èÆÀ
+    ¡¡¡¦boolÃͤȤÎÈæ³Ó¡¢¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó
+    ¡¡¡¦°Û¤Ê¤ë·¿¤ò¼¨¤¹¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó¡ÊƱ¤¸¥«¥Æ¥´¥ê¤Ë°¤¹¤ë¤â¤Î¤Î¤ß¡Ë
+    
+    »È¤¤Êý¤Ï bool_comparable ¤ÈƱ¤¸¡¢¡Ö¥Æ¥ó¥×¥ì¡¼¥È¤Ë¼«Ê¬¼«¿È¤Î·¿Ì¾¤òÆþ¤ì¤Æ·Ñ¾µ¡×¡£
+    ÂèÆó°ú¿ô¤Ï¥Ý¥¤¥ó¥¿¤ò³ÊǼ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î·¿¤ò¼¨¤·¤Þ¤¹¡£
+    ¾Êά²Äǽ¤ÊÂè»°°ú¿ô¤Ï¥Ý¥¤¥ó¥¿¤Î¥«¥Æ¥´¥ê¡¢Âè»°°ú¿ô¤¬Æ±¤¸¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÏÁê¸ßÈæ³Ó¤Ç¤­¤Þ¤¹¡£
+    ¾Êά¤·¤¿¾ì¹ç¡¢Â¾¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤ÏÈæ³Ó¤¬½ÐÍè¤Þ¤»¤ó¡Ê¤Ç¤âÄ̾ï¤ÏÈæ³Ó¤Ç¤­¤¿Êý¤¬Îɤ¤¤Ç¤¹¤è¡©¡Ë¡£
+    ¤µ¤é¤Ë¾Ü¤·¤¯¤Ï¡¢²¼¤ÎÍó¤ä¡¢¶äÅ·¥é¥¤¥Ö¥é¥ê¤ÇÄêµÁ¤µ¤ì¤¿¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Î¼ÂÁõ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+    
+  »È¤¤Êý¡§
+    // Ã±½ã¤Ê¥Ý¥¤¥ó¥¿¤Ø¤Î¥é¥Ã¥Ñ
+    
+    // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤òºî¤ë¾ì¹ç¡¢¤Þ¤º¥«¥Æ¥´¥ê¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡£
+    // Æ±¤¸¼ïÎà¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ç¡¢Æ±¤¸¥«¥Æ¥´¥ê¤ò¶¦Í­¤¹¤ë¤³¤È¤Ç¡¢
+    // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÁê¸ßÈæ³Ó¤¬¡ÊƱ¤¸¼ïÎà¤Î¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤Ë¸Â¤ê¡Ë²Äǽ¤Ë¤Ê¤ë¡£
+    struct trivial_ptr_category {}; // ¥«¥Æ¥´¥ê¥¯¥é¥¹¤Ï¥¿¥°¤Ê¤Î¤ÇŬÅö¤Ë
+    
+    // ËÜÂΠ
+    template<typename T>
+    class trivial_ptr :
+      public gintenlib::pointer_facade< trivial_ptr<T>, T, trivial_ptr_category > // ¤³¤¦»È¤¦
+    {
+     public:
+      trivial_ptr() : p(0) {}
+      explicit trivial_ptr( T* ptr ) : p( ptr ) {}
+      
+      // ²òÊü½èÍý¤È¤«¹Ô¤ï¤Ê¤¤
+      // ~trivial_ptr() throw () {}
+      
+      // get() ¤µ¤¨¤¢¤ì¤ÐOK
+      T* get() const { return p; }
+      
+      // reset ¤È¤« swap ¤â¤¢¤ë¤ÈÎɤ¤¤±¤É¡¢´ðËܤϤ³¤ì¤Ç½ªÎ»¡ª
+      
+     private:
+      T* p;
+      
+    };
+    
+    int main()
+    {
+      trivial_ptr<int> p1( new int() );
+      
+      // ¿§¡¹¤È¼«Æ°ÄêµÁ¤·¤Æ¤¯¤ì¤ë¤Î¤Ç
+      // ¤³¤ó¤Ê´¶¤¸¤Ë½ñ¤±¤ë
+      if( p1 )  // OK
+      {
+        cout << *p1 << endl; // OK
+      }
+      
+      trivial_ptr<vector<int> > p2( new vector<int>() );
+      cout << p2->size() << endl; // OK
+      
+      trivial_ptr<void> p0; // void ¤Ø¤Î¥Ý¥¤¥ó¥¿¤âŬÀڤ˿¶¤êʬ¤±¤Æ¤¯¤ì¤ë
+      assert( p0 != p1 ); // ¤â¤Á¤í¤óÈæ³Ó¤Ç¤­¤ë
+      
+      // todo: delete
+    }
+  
+  Ãí°Õ»ö¹à¡§
+    ¥Ý¥¤¥ó¥¿¤ËɬÍפʵ¡Ç½¤Ï¤¢¤é¤«¤¿ÍÑ°Õ¤·¤Æ¤¯¤ì¤ëÊØÍø¥¯¥é¥¹¤Ç¤¹¤¬¡¢
+    static_pointer_cast ¤ä¤é swap ¤ä¤é reset ¤ä¤é¤ÏÄêµÁ¤·¤Æ¤¯¤ì¤Þ¤»¤ó¡£Ëº¤ì¤Ê¤¤¤è¤¦¤Ë¡£
+    ¤Ê¤ª¡¢ friend ´Ø¿ô¤Î get_pointer ¤ä operator== ¤Ê¤ó¤«¤Ï¡¢gintenlib Ì¾Á°¶õ´ÖÆâ¤ËÄêµÁ¤µ¤ì¤Þ¤¹¡£
+    Ä̾ï¤Ï ADL ¤Ë¤è¤Ã¤Æ°Õ¼±¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤¬¡¢¸Å¤¤¥³¥ó¥Ñ¥¤¥é¤Ç¤Ï°ú¤Ã¤«¤«¤ë¤«¤â¡£
+
+*/
+
+#include "bool_comparable.hpp"
+
+#include <cassert>
+#include <boost/type_traits/add_reference.hpp>
+
+namespace gintenlib
+{
+  template< typename Derived, typename T, typename Category = Derived >
+  struct pointer_facade
+    : bool_comparable< pointer_facade< Derived, T, Category > >
+  {
+    // ¥¹¥Þ¡¼¥È¥Ý¥¤¥ó¥¿¤È¤·¤ÆɬÍפʤ¢¤ì¤³¤ì
+    typedef T  element_type;
+    typedef T  value_type;
+    typedef T* pointer;
+    // reference ¤Ï void ·¿¤Ø¤ÎÂбþ¤Î¤¿¤áÆüì
+    typedef typename boost::add_reference<T>::type reference;
+    
+    // »²¾È³°¤·¤È¥Ý¥¤¥ó¥¿¼èÆÀ
+    reference operator*() const
+    {
+      using namespace std;
+      assert( get_() != 0 );
+      return *get_();
+    }
+    pointer operator->() const
+    {
+      using namespace std;
+      assert( get_() != 0 );
+      return get_();
+    }
+    // for boost::mem_fn
+    friend pointer get_pointer( const Derived& target )
+    {
+      return target.get();
+    }
+    
+    // bool ¤È¤ÎÈæ³Ó
+    bool operator!() const
+    {
+      return !get_();
+    }
+    // operator safe_bool ¤Ï bool_comparable ¤Î´É³í
+    
+    // ÅùÃÍÈæ³Ó¤Ê¤É¤Ï³°Éô¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¼ÂÁõ
+  
+   private:
+    template<typename D, typename U, typename C>
+    friend class pointer_facade;
+    
+    // ÇÉÀ¸¥¯¥é¥¹¤Î get() ¤ò¸Æ¤Ó½Ð¤¹
+    pointer get_() const
+    {
+      return static_cast<const Derived*>(this)->get();
+    }
+    
+   protected:
+     pointer_facade(){}
+    ~pointer_facade(){}
+  
+  };  // pointer_facade<Derived, T, Category>
+  
+  // ¥Æ¥ó¥×¥ì¡¼¥ÈÈÇÁê¸ßÈæ³Ó
+  // ¥«¥Æ¥´¥ê¤¬Æ±¤¸¤â¤Î¤Ê¤éÁê¸ßÈæ³Ó£Ï£Ë
+  template<typename T, typename U, typename D1, typename D2, typename C>
+  inline bool operator==( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
+  {
+    return static_cast<const D1&>(lhs).get() == static_cast<const D2&>(rhs).get();
+  }
+  template<typename T, typename U, typename D1, typename D2, typename C>
+  inline bool operator!=( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
+  {
+    return static_cast<const D1&>(lhs).get() != static_cast<const D2&>(rhs).get();
+  }
+  template<typename T, typename U, typename D1, typename D2, typename C>
+  inline bool operator< ( const pointer_facade<D1, T, C>& lhs, const pointer_facade<D2, U, C>& rhs )
+  {
+    // °Û¤Ê¤ë¥Ý¥¤¥ó¥¿Æ±»Î¤ÎÈæ³Ó¤Ï¡¢
+    // boost::shared_ptr ¤Ç < ¤ò»È¤Ã¤Æ¤ë¤Î¤Ç¡¢¤³¤³¤Ç¤â < ¤ÇÈæ³Ó¤¹¤ë
+    return static_cast<const D1&>(lhs).get() < static_cast<const D2&>(rhs).get();
+  }
+
+}   // namespace gintenlib
+
+
+#endif  // #ifndef GINTENLIB_INCLUDED_POINTER_FACADE_HPP_
diff --git a/gintenlib/preprocessor/.svn/entries b/gintenlib/preprocessor/.svn/entries
new file mode 100755 (executable)
index 0000000..cddaa18
--- /dev/null
@@ -0,0 +1,96 @@
+10
+
+dir
+12
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib/trunk/gintenlib/preprocessor
+svn+ssh://ginten@ginten.sakura.ne.jp/home/ginten/var/svn/gintenlib
+
+
+
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5afde9dc-4444-11de-aefe-d0e08963c90a
+\f
+enable_if.hpp
+file
+
+
+
+
+2009-12-08T20:47:39.968750Z
+070fb5fb29eeced5749b6ff62c7aa2e1
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3030
+\f
+dequote.hpp
+file
+
+
+
+
+2009-12-08T20:24:19.062500Z
+fdcff83ddb67dd57c78efc0d8412099f
+2009-12-08T23:12:49.203639Z
+12
+ginten
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2806
+\f
diff --git a/gintenlib/preprocessor/.svn/text-base/dequote.hpp.svn-base b/gintenlib/preprocessor/.svn/text-base/dequote.hpp.svn-base
new file mode 100755 (executable)
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/.svn/text-base/enable_if.hpp.svn-base b/gintenlib/preprocessor/.svn/text-base/enable_if.hpp.svn-base
new file mode 100755 (executable)
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/storage.hpp b/gintenlib/storage.hpp
new file mode 100755 (executable)
index 0000000..9f687fd
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef GINTENLIB_INCLUDED_STORAGE_HPP_
+#define GINTENLIB_INCLUDED_STORAGE_HPP_
+
+/*
+
+      <gintenlib/storage.hpp>
+
+  storage ¡§ ¥á¥â¥êÎΰè³ÎÊÝÍÑ¥¯¥é¥¹
+
+  Àë¸À¡§
+    template< typename T >
+    struct storage
+      : boost::aligned_storage< sizeof(T), boost::alignment_of<T>::value > {};
+
+  µ¡Ç½¡§
+    T ·¿¤Î¥¯¥é¥¹¤ò³ÊǼ¤Ç¤­¤ë¤À¤±¤Î¥á¥â¥êÎΰè¤ò³ÎÊݤ·¤¿¤¤¾ì¹ç¡¢
+    °Âľ¤Ë char[sizeof(T)] ¤ò»È¤¦¤È¡¢¥¢¥é¥¤¥á¥ó¥È¤ÎÌäÂ꤬ȯÀ¸¤·¤Þ¤¹¡Ê¾Ü¤·¤¯¤ÏÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+    ¤½¤ì¤òÈò¤±¤ë°Ù¤ÎÉôÉʤ¬¡¢ boost ¤Ë¤¢¤ë alignment_storage ¥¯¥é¥¹¤Ç¤¢¤ê¡¢
+    boost::aligned_storage< sizeof(T), boost::alignment_of<T>::value >
+    ¤È¤¤¤¦·¿¤ò»È¤¦¤³¤È¤Ç¡¢ T ·¿¤Î¥¯¥é¥¹¤ò³ÊǼ¤Ç¤­¤ë¥á¥â¥êÎΰè¤ò³ÎÊݤ¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+    ¤·¤«¤·¤³¤ì¤Ë¤Ï¼åÅÀ¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Îɽ¸½¤Ç¤Ïľ´¶Åª¤Ë¡Ö T ·¿¤òÆþ¤ì¤ë¤¿¤á¤Î¾ì½ê¡×¤Èʬ¤«¤ê¤Þ¤»¤ó¡£
+    ¤½¤³¤Ç¡¢¤â¤Ã¤Èľ´¶Åª¤Êɽ¸½¤È¤·¤ÆÍÑ°Õ¤µ¤ì¤¿¤Î¤¬ gintenlib::storage<T> ¤Ç¤¹¡£
+    °ÕÌ£¤Ï¤½¤Î¤Þ¤Þ¡Ö T ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤Ç¤­¤ë¥á¥â¥êÎΰè¡×¡£
+    ¤½¤ÎÎΰè¤Î¥¢¥É¥ì¥¹¤ò¼èÆÀ¤·¤¿¤¤¾ì¹ç¤Ï address() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤Ç»È¤¨¤Þ¤¹¡£
+
+*/
+
+#include <boost/aligned_storage.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+namespace gintenlib
+{
+  // T ·¿¤ò¼ý¤á¤é¤ì¤ë¥á¥â¥êÎΰè
+  template<typename T>
+  struct storage
+    : boost::aligned_storage< sizeof(T), boost::alignment_of<T>::value > {};
+  
+}   // namespace gintenlib
+
+
+#endif  // #ifndef GINTENLIB_INCLUDED_STORAGE_HPP_
index 0a427c4..cdd4482 100644 (file)
@@ -137,17 +137,27 @@ namespace gintenlib_to_shared_impl_
 } // namespace gintenlib_to_shared_impl_
 
 
+// Å¾Á÷
+namespace gintenlib_to_shared_impl
+{
+  // ¤³¤ì¤âÇö¤¤¥é¥Ã¥Ñ
+  template<typename P>
+  inline boost::shared_ptr<typename P::element_type> to_shared_impl( const P& pt )
+  {
+    using namespace gintenlib_to_shared_impl_;
+    return 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 );
+    return ::gintenlib_to_shared_impl::to_shared_impl( pt );
   }
   
   // std::auto_ptr version