µ¡Ç½¡§
°ÅÌÛÊÑ´¹¤òÌÀ¼¨Åª¤Ë¹Ô¤¦¤¿¤á¤Î¥¥ã¥¹¥È¤Ç¤¹¡£ cast<void*>( 0 ) ¤Î¤è¤¦¤Ë»È¤¤¤Þ¤¹¡£
¼ç¤Ë¿½ÅÄêµÁ¤µ¤ì¤¿´Ø¿ô¤Î¸Æ¤Ó½Ð¤·¤òÀ©¸æ¤¹¤ë¤È¤¤Ë»È¤¤¤Þ¤¹¡£
+ Boost ¤Ë¤â implicit_cast ¤È¤¤¤¦Æ±µ¡Ç½¤Î¥¥ã¥¹¥È¤¬¤¢¤ê¤Þ¤¹¤¬¡¢
+ ¤³¤Á¤é¤Î¤Û¤¦¤¬Ê¸»ú¿ô¤¬¾¯¤Ê¤¤¤È¤¤¤¦ÅÀ¤ÇÍøÅÀ¤¬¤¢¤ê¤Þ¤¹¡£
»ÈÍÑÎ㡧
void hoge( int ){ cout << "int ÈǤǤ¹\n"; }
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_
--- /dev/null
+#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_
// ¤Û¤«¤Ë¡¢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>
// °ú¿ô¤ÎºÇÂçÃÍ
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 ) ) ); \
}
#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()
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, _ )
{
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>
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, _ )
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, _ )
--- /dev/null
+#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_
--- /dev/null
+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
--- /dev/null
+#ifndef GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
+#define GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
+
+/*
+ <gintenlib/options/exceptions.hpp>
+
+ ¥ª¥×¥·¥ç¥ó²òÀϥ饤¥Ö¥é¥êÍÑÎã³°¥¯¥é¥¹
+
+ Àë¸À¡§
+ // Îã³°´ðËÜ¥¯¥é¥¹
+ struct option_error : std::runtime_error;
+ // ¥ª¥×¥·¥ç¥ó»ØÄêʸ»úÎ󤬤ª¤«¤·¤¤
+ struct invalid_option_string : option_error;
+ // »ØÄꤵ¤ì¤Ê¤¤¥ª¥×¥·¥ç¥ó¤¬ÅϤµ¤ì¤¿
+ struct unknown_option : option_error;
+ // °ú¿ô¤¬É¬ÍפʤΤËÅϤµ¤ì¤Ê¤«¤Ã¤¿
+ struct option_requires_argument : option_error;
+
+ µ¡Ç½¡§
+ Îã³°ÍÑ¥¯¥é¥¹¤Ç¤¹¡£°Ê¾å¡£
+
+*/
+
+#include <stdexcept>
+
+namespace gintenlib
+{
+ // Îã³°´ðËÜ¥¯¥é¥¹
+ struct option_error : std::runtime_error
+ {
+ explicit option_error( const std::string& what_ )
+ : std::runtime_error( what_ ) {}
+ };
+ // ¥ª¥×¥·¥ç¥ó»ØÄêʸ»úÎ󤬤ª¤«¤·¤¤
+ struct invalid_option_string : option_error
+ {
+ explicit invalid_option_string( const std::string& optstr )
+ : option_error( "invalid option format string: " + optstr ) {}
+ };
+ // »ØÄꤵ¤ì¤Ê¤¤¥ª¥×¥·¥ç¥ó¤¬ÅϤµ¤ì¤¿
+ struct unknown_option : option_error
+ {
+ explicit unknown_option( const std::string& opt )
+ : option_error( "unknown option: " + opt ) {}
+ };
+ // °ú¿ô¤¬É¬ÍפʤΤËÅϤµ¤ì¤Ê¤«¤Ã¤¿
+ struct option_requires_argument : option_error
+ {
+ explicit option_requires_argument( const std::string& opt )
+ : option_error( "option requres an argument: " + opt ) {}
+ };
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_OPTIONS_INCLUDED_EXCEPTIONS_HPP_
--- /dev/null
+#ifndef GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
+#define GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
+
+/*
+ <gintenlib/options/options.hpp>
+
+ options ¡§ getopt Ū¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó²òÀÏ
+
+ Àë¸À¡§
+ struct options
+ {
+ // »ØÄꤵ¤ì¤¿Ê¸»úÎó¤Ç¥ª¥×¥·¥ç¥ó²òÀÏ¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë
+ // ʸ»úÎó¤Ï´ðËÜŪ¤Ë getopt ¸ß´¹¡¢ËÁƬ¤Î : ¤È - ¤ÎÆ°ºî¤Î¤ß°ã¤¦
+ explicit options( const std::string& optstr, int argc, char* argv[] );
+
+ // ¼ÂºÝ¤Ë¥ª¥×¥·¥ç¥ó¤ò²òÀϤ¹¤ë
+ typedef int result_type;
+ result_type operator()();
+
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
+ int optind() const;
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀßÄꤹ¤ë
+ void set_optind( int new_index = 1 );
+
+ // °ú¿ô
+ const std::string& optarg() const;
+
+ // ¥¨¥é¡¼»þ¤ËÆɤó¤Ç¤¤¤¿Ê¸»ú
+ int optopt() const;
+
+ }; // struct options
+
+ µ¡Ç½¡§
+ ¥³¥ó¥¹¥È¥é¥¯¥¿¤ÇÍ¿¤¨¤é¤ì¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤ò¸µ¤Ë¡¢¥×¥í¥°¥é¥à¥ª¥×¥·¥ç¥ó¤ò²òÀϤ·¤Þ¤¹¡£
+ ¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï´ðËÜŪ¤Ë£Ç£Î£Õ¤Î getopt ¸ß´¹¤Ç¤¹¤¬¡¢¼ã´³¤Î°ã¤¤¤¬¤¢¤ê¡¢
+ ¤Þ¤ºÌ¤ÃΤΥª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¡¢'?'¤òÊÖ¤µ¤ºÎã³°¤òÅꤲ¤ëÅÀ¡£
+ ¤³¤ì¤Ï ':' ¤ò¥Õ¥©¡¼¥Þ¥Ã¥È¤ÎƬ¤ËÃÖ¤¯¤³¤È¤Ç¡¢Îã³°¤òÅꤲ¤º '?' ¤òÊÖ¤¹¤è¤¦¤ËÊѹ¹¤Ç¤¤Þ¤¹¡£
+ ¤³¤Î¤È¤¡¢°ú¿ô¤¬Â¤ê¤Ê¤¤¾ì¹ç¤Ï ':' ¤òÊÖ¤·¤Þ¤¹¡Ê¤³¤³¤Ï getopt ¤ÎÆ°ºî¤ÈƱ¤¸¡Ë¡£
+ ¤Þ¤¿¥ª¥×¥·¥ç¥óʸ»úÎó¤ÎƬ¤Ë '-' ¤ò»ØÄꤹ¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡Ê£Ç£Î£Õ¤Î»ÅÍͤ¬Îɤ¯Ê¬¤«¤é¤Ê¤«¤Ã¤¿¤Î¤Ç¡Ë¡£
+ ¤Þ¤¿´Ä¶ÊÑ¿ô POSIXLY_CORRECT ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Æ¤âÆ°ºî¤Ï¤Ê¤Ë¤âÊѤï¤ê¤Þ¤»¤ó¡£
+ '+' ¤Ç»Ï¤Þ¤ëʸ»úÎó¤òÅϤ¹¤³¤È¤ÇÂн褷¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¶ñÂÎŪ¤Ê¥Õ¥©¡¼¥Þ¥Ã¥È¤ÎÍ¿¤¨Êý¤Ï°Ê²¼¤ÎÄ̤ꡧ
+ ñÆȤÎʸ»ú¤Ï¡¢°ú¿ô¤ò¼è¤é¤Ê¤¤¥ª¥×¥·¥ç¥ó¤ò¼¨¤¹¡£
+ ʸ»ú¤Î¸å¤Ë ':' ¤¬Â³¤¤¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤Ï°ú¿ô¤ò¼è¤ë¡£
+ ʸ»ú¤Î¸å¤ËÆó¤Ä¤Î ':' ¤¬Â³¤¤¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤Ï°ú¿ô¤ò¼è¤ê¤¦¤ë¡£
+ Î㡧
+ "ab:c::d" ¤ÈÅϤµ¤ì¤¿¤é¡¢a ¤È d ¤Ï°ú¿ô¤Ê¤·¡¢ b ¤Ï°ú¿ô¤¢¤ê¡¢ c ¤Ï°ú¿ô¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¤¤¤¤
+
+ »ÈÍÑÎ㡧
+ // usage: ¥³¥Þ¥ó¥É̾ ¥ª¥×¥·¥ç¥óʸ»úÎó ²òÀϤµ¤»¤¿¤¤°ú¿ô
+ // ¤³¤¦µ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ options ¤Î¤Û¤ÜÁ´µ¡Ç½¤ò¥Æ¥¹¥È¤Ç¤¤ëÎã¤Ç¤¹
+ #include <gintenlib/options.hpp>
+ #include <gintenlib/cast.hpp>
+
+ #include <iostream>
+ using namespace std;
+
+ int main( int argc, char* argv[] )
+ {
+ // °ÅÌÛ¥¥ã¥¹¥È
+ using gintenlib::cast;
+
+ try
+ {
+ if( argc < 2 ){ throw gintenlib::option_error("missing 'OPTSTR'"); }
+
+ // argv[1] ¤ÏÆÃÊ̤ʰú¿ô
+ gintenlib::options opt( argv[1], argc, argv );
+ // ¤Ê¤Î¤Ç²òÀϤµ¤»¤Ê¤¤
+ opt.set_optind( 2 );
+
+ for(;;)
+ {
+ // ²òÀϤµ¤»¤ë¡£ ch ¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤Îʸ»ú¤¬Æþ¤ë
+ int ch = opt();
+ if( ch == -1 ){ break; } // -1: ²òÀϽª¤ï¤ê
+
+ switch(ch)
+ {
+ case '?':
+ // ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "unknown option '" << cast<char>( opt.optopt() ) << "' is given. continue...\n";
+ break;
+
+ case ':':
+ // Ʊ¤¸¤¯ ':' ¤Ç»Ï¤Þ¤ë¥ª¥×¥·¥ç¥óʸ»úÎó¤Ø¤ÎÂбþ
+ cout << "option '" << cast<char>( opt.optopt() ) << "'requires argument. continue...\n";
+ break;
+
+ default:
+ // ¥ª¥×¥·¥ç¥ó°ìÈÌ
+ cout << "option '" << cast<char>( ch ) << "' is given.\n";
+
+ // °ú¿ô¤Ï optarg() ¤Ç³ÍÆÀ
+ // °ú¿ô¤¬Ìµ¤¤¾ì¹ç¤Ï string() ¤¬Æþ¤ë
+ if( !opt.optarg().empty() )
+ {
+ cout << " argument: " << opt.optarg() << endl;
+ }
+ break;
+
+ }
+ }
+
+ // ²òÀϽªÎ»¡£Í¾¤Ã¤¿¥ª¥×¥·¥ç¥ó¤Ï argv[opt.optind()] ¡Á argv[argc-1] ¤Ë½¸¤á¤é¤ì¤ë
+ // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó°ú¿ô¤¬È󥪥ץ·¥ç¥ó°ú¿ô¤Î¸å¤Ë¤¢¤ë¾ì¹ç¡¢ argv ¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤ë
+ // ¤³¤ÎÆ°ºî¤òÈò¤±¤¿¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¤Î°ú¿ô¤ò '+' ¤Ç»Ï¤á¤ì¤Ð¤è¤¤
+ cout << "\nextra options are:\n";
+ for( int i = opt.optind(); i < argc; ++i )
+ {
+ cout << argv[i] << endl;
+ }
+ }
+ catch( gintenlib::option_error& e )
+ {
+ // ¥ª¥×¥·¥ç¥ó²òÀϤ˼ºÇÔ¤·¤ÆÎã³°¤¬Åꤲ¤é¤ì¤¿¾ì¹ç¤Ï¤³¤Á¤é¤ËÈô¤Ö
+ cerr << e.what() << endl;
+ cerr << "usage: " << argv[0] << " OPTSTR [OPTIONS]\n";
+
+ return 1;
+ }
+ catch( std::exception& e )
+ {
+ // ¤½¤Î¤Û¤«¤ÎÎã³°
+ cerr << e.what() << endl;
+ return 1;
+ }
+ } // main( argc, argv )
+
+
+ Ê䡧
+ ¡¦¼ç¤Ë <unistd.h> ¤¬¥¤¥ó¥¯¥ë¡¼¥É¤Ç¤¤Ê¤¤½èÍý·Ï¸þ¤±¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+ ¡¦¤¢¤È¡¢¤â¤í¤â¤í¤Î»ö¾ð¤Ç <unistd.h> ¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¤¯¤Ê¤¤¾ì¹ç¤È¤«¤Ë¤â¡£
+ ¡¦¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤ò»È¤ï¤Ê¤¤¡¢¼ºÇÔ»þ¤ÏÎã³°¤òÅꤲ¤Æ¤¯¤ì¤ë¡¢¤È¤¤¤¦¤Î¤â¥á¥ê¥Ã¥È¤Ç¤¹¡£
+ ¡¦¾åµ¤Î¤è¤¦¤ÊÍýͳ¤¬Ìµ¤¤¤Ê¤é¡¢ÁÇľ¤Ë getopt ¤ò»È¤Ã¤¿¤Û¤¦¤¬¤è¤¤¤È»×¤¤¤Þ¤¹¡£
+ ¡¦ÂåÂؼêÃʤȤ·¤Æ¤Ï boost ¤Î progtam_options ¤Ã¤Æ¤Î¤â¤¢¤ë¤±¤É¡¢¥ê¥ó¥¯¤·¤Ê¤¤ã¤¤¤±¤Ê¤¤¤Î¤¬ÌÌÅÝ¡£
+ ¡¦¤¢¤È¡¢¤¤¤í¤¤¤í¥ª¡¼¥Ð¡¼¥¹¥Ú¥Ã¥¯²á¤®¤ëµ¤¤¬¤·¤Æµ¤·Ú¤Ë¤Ï»È¤¤¤Ë¤¯¤¤¤Ç¤¹¡£¸Ä¿ÍŪ¤Ë¡£
+ ¡¦¤Þ¡¼Â礷¤¿½èÍý¤ò¤·¤Ê¤¤¤Ê¤é¡¢¤³¤ì¤ò»È¤Ã¤È¤±¡£¥Ø¥Ã¥À¤Î¥¤¥ó¥¯¥ë¡¼¥É¤Î¤ß¤ÇºÑ¤à¤·¤Í¡£
+ ¡¦¥Æ¥ó¥×¥ì¡¼¥È¡© ¤Ê¤Ë¤½¤ìÈþÌ£¤·¤¤¤Î¡©
+
+*/
+
+#include "exceptions.hpp"
+
+#include <map>
+#include <string>
+#include <cassert>
+#include <algorithm>
+#include "../tribool.hpp"
+#include "../to_string.hpp"
+#include "../cast.hpp"
+
+namespace gintenlib
+{
+ // ¥ª¥×¥·¥ç¥ó²òÀϵ¡
+ struct options
+ {
+ // optstr ¤Ç¼¨¤µ¤ì¤ë¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó¤ò²òÀϤ¹¤ë
+ explicit options( const std::string& optstr, int argc_, char* argv_[] )
+ : argc(argc_), argv(argv_), index(1), index_max(argc), next_char(0), opt('?'),
+ posixly_correct(false), throws_on_error(true)
+ {
+ using namespace std;
+ char prev = 0;
+
+ for( string::const_iterator ite = optstr.begin(), end = optstr.end();
+ ite != end; ++ite )
+ {
+ char ch = *ite;
+
+ if( ch == ':' )
+ {
+ // ¥³¥í¥óµ¹æ¤ÏľÁ°¤Ë²òÀϤ·¤¿Ê¸»ú¤Ë¤è¤Ã¤ÆÆ°ºî¤òÀÚ¤êÂؤ¨¤ë
+ if( prev == 0 )
+ {
+ // ʸƬ¤Î¥³¥í¥ó¤Ï¡ÖÎã³°¤òÅꤲ¤Ê¤¤¡×»ØÄê¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë
+ throws_on_error = false;
+ }
+ else
+ {
+ // ľÁ°¤Îʸ»ú¤ò¸¡º÷¤¹¤ë
+ map_type::iterator pos = m.find( prev );
+ // ¸«¤Ä¤«¤é¤Ê¤¤¤³¤È¤ÏͤêÆÀ¤Ê¤¤
+ assert( pos != m.end() );
+
+ tribool& has_arg = (*pos).second;
+ if( !has_arg )
+ {
+ // °ì²óÌܤΠ: ¤Î»þ¤Ï¡¢°ú¿ôɬ¿Ü
+ has_arg = true;
+ }
+ else
+ {
+ // Æó²óÌܰʹߤϡ¢°ú¿ôǤ°Õ
+ has_arg = indeterminate;
+ }
+ }
+ }
+ else if( ch == '+' )
+ {
+ if( prev != 0 )
+ {
+ // + »ØÄê¤ÏËÁƬ¤Ë¤Î¤ßÃÖ¤±¤ë
+ throw invalid_option_string( optstr );
+ }
+ // ¤³¤Î»ØÄ꤬¤¢¤Ã¤¿¾ì¹ç¡¢°ú¿ô¤Î½çÈÖ¤ÏÆþ¤ìÂؤ¨¤Ê¤¤
+ posixly_correct = true;
+ }
+ else if( ch == '-' )
+ {
+ // - µ¹æ¤ÏGNU³ÈÄ¥¤Ë¸ºß¤¹¤ë¤¬¡¢¤è¤¯Ê¬¤«¤é¤Ê¤¤¤Î¤Ç¾ï¤ËÉÔÀµ¤È¤¤¤¦¤³¤È¤Ë¤¹¤ë¡ÊÍ×½¤Àµ¡Ë
+ throw invalid_option_string( optstr );
+ }
+ else if( ch == '?' )
+ {
+ // ? µ¹æ¤Ï¥ª¥×¥·¥ç¥óʸ»ú¤È¤·¤Æ¤Ï»È¤¨¤Ê¤¤¤Î¤ÇÉÔÀµ
+ throw invalid_option_string( optstr );
+ }
+ else
+ {
+ // ¾°ìÈÌ
+ // ':' '+' '-' '\0' °Ê³°¤Ê¤é¤É¤ó¤Êʸ»ú¤Ç¤â¤¤¤¤
+ if( m.count( ch ) != 0 )
+ {
+ // Ʊ¤¸¥ª¥×¥·¥ç¥óʸ»ú¤òÆó²óÄêµÁ¤·¤Á¤ã¥À¥á
+ throw invalid_option_string( optstr );
+ }
+ // ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï°ú¿ô¤Ê¤·
+ m[ch] = false;
+ // : »ØÄꤵ¤ì¤¿¤È¤¤Î¤¿¤á¤Ë¡¢Ê¸»ú¤òÊݸ¤¹¤ë
+ prev = ch;
+ }
+
+ } // for
+ } // constructor
+
+ // ¼ÂºÝ¤Î²òÀϤϤ³¤Á¤é¤Ç
+ typedef int result_type;
+ result_type operator()()
+ {
+ using namespace std; // for assert
+
+ // ¤Þ¤º¥¤¥ó¥Ç¥Ã¥¯¥¹¤Î¥Á¥§¥Ã¥¯
+ if( index_max <= index ){ return -1; }
+ // °ú¿ôʸ»úÎó¤Î½é´ü²½
+ arg = string();
+
+ // ¼¡¤Ë½èÍý¤¹¤ëʸ»ú¤¬»ØÄꤵ¤ì¤Æ̵¤¤¾ì¹ç¡ÊÉáÄ̤Ϥ½¤¦¡Ë¤Ï
+ // argv[index] ¤Ë¿Ê¤à
+ if( !next_char )
+ {
+ next_char = argv[index];
+ assert( next_char != 0 );
+
+ // ¥ª¥×¥·¥ç¥óʸ»úÎó¤À¤«¤é¡¢'-' ¤Ç¤Ï¤¸¤Þ¤ë¤Ï¤º
+ char ch = *next_char;
+ if( ch == '-' )
+ {
+ // OK¡£¤½¤Î¼¡¤Ë¶½Ì£¤¬¤¢¤ë
+ ++next_char;
+ }
+ else
+ {
+ // ¥ª¥×¥·¥ç¥óʸ»úÎó¤Ç¤Ï¤Ê¤«¤Ã¤¿
+
+ // ¤È¤ê¤¢¤¨¤º¥Ý¥¤¥ó¥¿¤Ï¥ê¥»¥Ã¥È
+ next_char = 0;
+
+ if( posixly_correct )
+ {
+ // POSIX Ū¤Ë¤Ï¡¢°ì²ó¼ºÇÔ¤¹¤ë¤È¤½¤ì¤Ç½ª¤ï¤ê
+ return -1;
+ }
+ else
+ {
+ // GNU ³ÈÄ¥¤À¤È¡¢°ú¿ô¤Î½ç½ø¤òÆþ¤ìÂؤ¨¤Æ¥Þ¥Ã¥Á¥ó¥°¤ò³¤±¤ë
+ for( int i = index + 1; i < index_max; ++i )
+ {
+ char* p = argv[i];
+ if( *p == '-' )
+ {
+ rotate( &argv[index], &argv[i], &argv[argc] );
+ index_max -= i - index;
+ return (*this)();
+ }
+ }
+
+ // ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿
+ // ʤӽç¤òÉü¸µ¤¹¤ë
+ rotate( &argv[index], &argv[index_max], &argv[argc] );
+ index_max = index;
+
+ return -1;
+ }
+ }
+ }
+
+ // ¤³¤Î»þÅÀ¤Ç¡¢next_char ¤Ï¥ª¥×¥·¥ç¥óʸ»ú¤ò»Ø¤·¤Æ¤¤¤ëȦ
+ char ch = *next_char;
+
+ if( ch == 0 )
+ {
+ // - ¤Î¤ß¤Î°ú¿ô¤¬ÅϤµ¤ì¤¿
+ // ¤³¤ì¤ÏÈ󥪥ץ·¥ç¥óʸ»úÎó¤È¤·¤Æ°·¤¦
+ next_char = 0;
+ return -1;
+ }
+ else if( ch == '-' )
+ {
+ // '--' ¤ÏŤ¤¥ª¥×¥·¥ç¥ó¤«¡¢¥ª¥×¥·¥ç¥ó¤Î½ªÎ»¤òɽ¤¹
+ ++next_char;
+ if( *next_char != 0 )
+ {
+ // Ť¤¥ª¥×¥·¥ç¥ó¤Ë¤ÏÈóÂбþ
+ throw unknown_option( "--" + to_str(next_char) );
+ }
+
+ // Ť¤¥ª¥×¥·¥ç¥ó¤Ç¤Ï¤Ê¤¤¤Î¤Ç¥ª¥×¥·¥ç¥ó¤Î½ªÎ»¤òɽ¤¹
+ // ½ªÎ»½èÍý¤ò¤·¤Æ
+ terminate_analysis_();
+ // ¤ª¤·¤Þ¤¤
+ return -1;
+ }
+
+ // ch ¤ò¥Þ¥Ã¥×¤«¤é¸¡º÷¤¹¤ë
+ map_type::const_iterator ite = m.find( ch );
+ if( ite == m.end() )
+ {
+ // ¸ºß¤·¤Ê¤¤¤è¤¦¤Ê¤é¡¢¤½¤Î¥ª¥×¥·¥ç¥ó¤ò optopt ¤Ë³ÊǼ¤·
+ opt = ch;
+ // °ì±þ¡¢Ê¸»ú¤ò¼¡¤Ë¿Ê¤á¤Æ
+ advance_next_char_();
+
+ // Îã³°¤òÅꤲ¤ë
+ if( throws_on_error )
+ {
+ throw unknown_option( "-" + to_str( cast<char>(ch) ) );
+ }
+
+ // Åꤲ¤Ê¤¤¾ì¹ç¤Ï '?' ¤òÊÖ¤¹
+ return '?';
+ }
+
+ // °ú¿ô¤Ï¤¢¤ë¡©
+ tribool has_arg = (*ite).second;
+ if( !has_arg )
+ {
+ // °ú¿ô¤Î¤Ê¤¤¾ì¹ç
+ // ¤È¤ê¤¢¤¨¤º¼¡¤Îʸ»ú¤Ë¿Ê¤á¤ë
+ advance_next_char_();
+
+ // ¤½¤Îʸ»ú¤òÊÖ¤¹
+ return ch;
+ }
+
+ // ¤³¤Î»þÅÀ¤Ç¡¢°ú¿ô¤Ï¡Ö¤¢¤ë¡×¤«¡ÖǤ°Õ¡×¤«¤Î¤É¤Á¤é¤«
+ ++next_char;
+ if( *next_char != 0 )
+ {
+ // ³¤¤¬¤¢¤ë¤Ê¤é¡¢¤½¤¤¤Ä¤¬°ú¿ôʸ»úÎó
+ arg = string( next_char );
+
+ advance_index_();
+ return ch;
+ }
+
+ // °ú¿ôɬ¿Ü¤«Èݤ«
+ if( has_arg )
+ {
+ // ɬ¿Ü¤Ê¤é¡¢¼¡¤Î argv ¤ò°ú¿ô¤È¤ß¤Ê¤¹
+ advance_index_();
+
+ if( index_max <= index )
+ {
+ return missing_argument_found_( ch );
+ }
+
+ // ¼¡¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¡¢¤Þ¤ë¤Þ¤ë°ú¿ô¤È¸«¤Ê¤¹
+ arg = argv[index];
+ // ¤¿¤À¤· argv[index] ¤¬ "--" ¤Î¤È¤¤ÏÎã³°
+ if( arg == "--" )
+ {
+ arg = string();
+ terminate_analysis_();
+ return missing_argument_found_( ch );
+ }
+
+ // ¤µ¤é¤Ë²òÀϹԤò¿Ê¤á¤ë
+ advance_index_();
+ return ch;
+ }
+ else
+ {
+ // °ú¿ô¤¬¾Êά²Äǽ¤Ç¡¢¥ª¥×¥·¥ç¥óʸ»ú¤ÈƱ»þ¤Ë°ú¿ô¤¬ÅϤµ¤ì¤Æ¤¤¤Ê¤¤¤Ê¤é
+ // °ú¿ô¤ò¶õʸ»úÎó¤Ë¤·¤Æ ch ¤òÊÖ¤¹
+ advance_index_();
+ return ch;
+ }
+
+ assert( !"should not get here." );
+ return '?';
+ }
+
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
+ int optind() const { return index; }
+ // ¼¡¤Ë½èÍý¤¹¤ë°ú¿ô¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀßÄꤹ¤ë
+ void set_optind( int new_index = 1 )
+ {
+ if( new_index < 1 ){ new_index = 1; }
+
+ index = new_index; next_char = 0; index_max = argc;
+ arg = std::string(); opt = '?';
+ }
+
+ // °ú¿ô
+ const std::string& optarg() const { return arg; }
+
+ // ¥¨¥é¡¼»þ¤ËÆɤó¤Ç¤¤¤¿Ê¸»ú
+ int optopt() const { return opt; }
+
+ private:
+ typedef std::map< char, tribool > map_type;
+ map_type m;
+ int argc;
+ char** argv;
+ int index, index_max;
+ const char* next_char;
+ std::string arg;
+ int opt;
+ bool posixly_correct, throws_on_error;
+
+ // ÆâÉô´Ø¿ô
+ // ²òÀϤ¹¤ë¹Ô¤ò°ì¤Ä¿Ê¤á¤ë
+ void advance_index_()
+ {
+ ++index;
+ next_char = 0;
+ }
+ // ʸ»ú¤ò°ìʸ»ú¿Ê¤á¤ë
+ void advance_next_char_()
+ {
+ // ¤È¤ê¤¢¤¨¤º¼¡¤Îʸ»ú¤Ë¿Ê¤á¤ë
+ ++next_char;
+
+ if( *next_char == 0 )
+ {
+ // ¼¡¤Îʸ»ú¤¬Â¸ºß¤·¤Ê¤¤¤Ê¤é¡¢²òÀϤΥ¤¥ó¥Ç¥Ã¥¯¥¹¤ò¿Ê¤á¤ë
+ ++index;
+ next_char = 0;
+ }
+ }
+ // °ú¿ô¤¬Â¤ê¤Ê¤¤
+ int missing_argument_found_( int ch )
+ {
+ // °ú¿ôÉÔÂ
+ opt = ch;
+
+ // Îã³°¤òÅꤲ¤ë
+ if( throws_on_error )
+ {
+ throw option_requires_argument( "-" + to_str( cast<char>(ch) ) );
+ }
+
+ return ':';
+ }
+ // '--' ¤ËÁø¶ø¤·¤¿
+ void terminate_analysis_()
+ {
+ // ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò¿Ê¤á¤Æ
+ advance_index_();
+
+ // ʤÓÂؤ¨¤ÎÅÓÃæ¤Ê¤éʤӽç¤òÉü¸µ¤¹¤ë
+ if( argc != index_max )
+ {
+ std::rotate( &argv[index], &argv[index_max], &argv[argc] );
+ }
+
+ // ¤³¤ì°Ê¾å¤Ï²òÀϤ·¤Ê¤¤¤è
+ index_max = index - 1;
+ }
+
+ }; // struct options
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_OPTIONS_INCLUDED_OPTIONS_HPP_
--- /dev/null
+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
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
+#define GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
+
+/*
+
+ <gintenlib/plane/angle.hpp>
+
+ angle ¡§ Ê¿Ì̳Ñ
+
+ µ¡Ç½¡§
+ Ê¿Ì̳Ѥò°·¤¦¥¯¥é¥¹¡£
+ £Ã¡Ü¡Ü¤Ë¤ª¤¤¤Æ³ÑÅÙ¤Ï radian ¤Ç°·¤¤¤Þ¤¹¤¬¡¢¤¿¤Þ¤Ë degree ¤â»È¤¤¤¿¤¯¤Ê¤ë¤Ç¤·¤ç¤¦¡£
+ ¤½¤¦¤¤¤¦¤È¤¤Ë¡¢Æó¤Ä¤Îɽ¤·Êý¤òº®Æ±¤·¤Ê¤¤¤è¤¦¤Ë°·¤¨¤ë¥¯¥é¥¹¤Ç¤¹¡£
+ ¤¢¡¢¤½¤ì¤«¤é³ÑÅÙ¤ÎÀµµ¬²½¡Ê-¦Ð¤«¤é¦Ð¤Î´Ö¤Ë¤Ê¤ë¤è¤¦Ä´À᤹¤ë¡Ë¤â¤Ç¤¤Þ¤¹¡£¤Ä¤¤¤Ç¤Ë¡£
+
+ ¼ç¤ËÃÆËë¤òºî¤ë¤È¤¤Ë»È¤¦ÄøÅ٤Υ¯¥é¥¹¤Ç¤¹¡£
+
+ »ÈÍÑÎ㡧
+ angle x, y = degree(60); // x ¤Ï 0, y ¤Ï 60¡ë
+ // »°³Ñ´Ø¿ô
+ cout << sin(x) << ", " << sin(y) << endl;
+ // µÕ»°³Ñ´Ø¿ô
+ angle z = angle::asin(0.5);
+ // ¿ôÃͤËÊÑ´¹
+ cout << "z ¤Ï " << to_rad(z) << " ¥é¥¸¥¢¥ó¡¢ " << to_deg(z) << " Å٤Ǥ¹¡£";
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+
+#include "../math.hpp" // for M_PI
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // angle : Ê¿Ì̳Ñ
+ template<typename Real>
+ struct basic_angle
+ : private boost::totally_ordered< basic_angle<Real> >,
+ private boost::additive< basic_angle<Real> >,
+ private boost::multiplicative< basic_angle<Real>, Real >,
+ private boost::modable< basic_angle<Real> >
+ {
+ typedef Real real_type;
+ real_type theta;
+
+ basic_angle()
+ : theta() {}
+
+ template<typename T>
+ basic_angle( const basic_angle<T>& src )
+ : theta( src.theta ) {}
+
+ // ¼Â¿ôÃͤ«¤éÀ¸À®¡¢Ã±°Ì¤Ï rad
+ explicit basic_angle( real_type theta_ )
+ : theta(theta_) {}
+
+ // theta ¤ÎÃͤòÆÀ¤ë
+ real_type to_deg() const
+ {
+ return theta * 180 / M_PI;
+ }
+ friend real_type to_deg( const basic_angle& target )
+ {
+ return target.to_deg();
+ }
+ friend real_type deg( const basic_angle& target )
+ {
+ return target.to_deg();
+ }
+ real_type to_rad() const
+ {
+ return theta;
+ }
+ friend real_type to_rad( const basic_angle& target )
+ {
+ return target.to_rad();
+ }
+ friend real_type rad( const basic_angle& target )
+ {
+ return target.to_rad();
+ }
+
+ // operator overloads
+ // Èæ³Ó
+ friend bool operator==( const basic_angle& lhs, const basic_angle& rhs )
+ {
+ return lhs.theta == rhs.theta;
+ }
+ friend bool operator<( const basic_angle& lhs, const basic_angle& rhs )
+ {
+ return lhs.theta < rhs.theta;
+ }
+ // ²Ã¸º»»
+ basic_angle& operator+=( const basic_angle& rhs )
+ {
+ theta += rhs.theta;
+ return *this;
+ }
+ basic_angle& operator-=( const basic_angle& rhs )
+ {
+ theta -= rhs.theta;
+ return *this;
+ }
+ // Éä¹æȿž
+ basic_angle operator-() const
+ {
+ return basic_angle( -theta );
+ }
+ // ³Ý¤±»»¡¢³ä¤ê»»
+ basic_angle& operator*=( const real_type& rhs )
+ {
+ theta *= rhs;
+ return *this;
+ }
+ basic_angle& operator/=( const real_type& rhs )
+ {
+ theta /= rhs;
+ return *this;
+ }
+ // Èæ¤Î»»½Ð
+ real_type operator/( const basic_angle& rhs ) const
+ {
+ return theta / rhs.theta;
+ }
+ // ¾ê;±é»»
+ // std::fmod ¤ò¸Æ¤Ó½Ð¤¹¤À¤±
+ basic_angle& operator%=( const basic_angle& rhs )
+ {
+ using std::fmod;
+
+ theta = fmod( theta, rhs.theta );
+
+ return *this;
+ }
+ // ¥Ù¥¯¥È¥ë¤ËÂФ·¤Æ³Ý¤±»»¤¹¤ë¤È²óžÁàºî
+ // ¤¿¤À¤·¡¢º¸¤«¤é³Ý¤±¤¿»þ¤Î¤ß
+ basic_vector<Real> operator*( const basic_vector<Real>& target ) const
+ {
+ return rotate( target, *this );
+ }
+
+ // [ -¦Ð, ¦Ð ] ¤ÎÈϰϤËÊäÀµ
+ basic_angle& normalize()
+ {
+ using std::fmod;
+
+ if( theta > M_PI )
+ {
+ // ¦Ð¤À¤±¤º¤é¤·¤Æ¸µ¤ËÌ᤹
+ theta = fmod( theta + M_PI, M_PI * 2 ) - M_PI;
+ }
+ else if( theta < -M_PI )
+ {
+ // ¤Á¤ç¤Ã¤È¤ä¤ä¤³¤·¤¤¤±¤Éʬ¤«¤ë¤Ï¤º¡Ê¤¿¤Ö¤ó¡Ë
+ theta = -fmod( -theta + M_PI, M_PI * 2 ) + M_PI;
+ }
+
+ // °ì±þ³Î¤«¤á¤Æ¤ª¤¯¤è¡©
+ assert( -M_PI <= theta && theta <= M_PI );
+
+ return *this;
+ }
+ friend basic_angle normalized( const basic_angle& target )
+ {
+ basic_angle temp = target;
+ return temp.normalize();
+ }
+ // [ 0, 2¦Ð ) ¤ÎÈϰϤËÊäÀµ
+ basic_angle& unique()
+ {
+ using std::fmod;
+
+ if( theta >= M_PI * 2 )
+ {
+ theta = fmod( theta, M_PI * 2 );
+ }
+ else if( theta < 0 )
+ {
+ theta = M_PI * 2 - fmod( -theta, M_PI * 2 );
+ }
+
+ // °ì±þ³Î¤«¤á¤Æ¤ª¤¯¤è¡©
+ assert( 0 <= theta && theta < M_PI * 2 );
+
+ return *this;
+ }
+ friend basic_angle uniqued( const basic_angle& target )
+ {
+ basic_angle temp = target;
+ return temp.unique();
+ }
+
+ // »°³Ñ´Ø¿ô
+ #define GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( func ) \
+ real_type func() const \
+ { \
+ using std::func; \
+ return func( theta ); \
+ } \
+ friend real_type func( const basic_angle& x ) \
+ { \
+ return x.func(); \
+ }
+
+ // ¼ÂºÝ¤ËÀ¸À®
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( sin )
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( cos )
+ GINTENLIB_PLANE_ANGLE_GEN_FUNCTION( tan )
+
+ #undef GINTENLIB_PLANE_ANGLE_GEN_FUNCTION
+
+ // µÕ»°³Ñ´Ø¿ô
+ static basic_angle asin( real_type x )
+ {
+ using std::asin;
+ return basic_angle( asin(x) );
+ }
+ static basic_angle acos( real_type x )
+ {
+ using std::acos;
+ return basic_angle( acos(x) );
+ }
+ static basic_angle atan( real_type x )
+ {
+ using std::atan;
+ return basic_angle( atan(x) );
+ }
+ static basic_angle atan2( real_type y, real_type x )
+ {
+ using std::atan2;
+ return basic_angle( atan2( y, x ) );
+ }
+
+ };
+ typedef basic_angle<double> angle;
+
+ // ¥é¥¸¥¢¥ó <--> ÅÙ ´¹»»
+ template<typename Real>
+ Real degree( const basic_angle<Real>& x )
+ {
+ return x.to_deg();
+ }
+ template<typename Real>
+ basic_angle<Real> degree( Real deg )
+ {
+ return basic_angle<Real>( deg * M_PI / 180 );
+ }
+ template<typename Real>
+ Real radian( const basic_angle<Real>& x )
+ {
+ return x.to_rad();
+ }
+ template<typename Real>
+ basic_angle<Real> radian( Real rad )
+ {
+ return basic_angle<Real>( rad );
+ }
+ // û½Ì̾
+ template<typename Real>
+ basic_angle<Real> deg( Real deg_ )
+ {
+ return degree( deg_ );
+ }
+ template<typename Real>
+ basic_angle<Real> rad( Real rad_ )
+ {
+ return radian( rad_ );
+ }
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_ANGLE_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_FWD_HPP_
+#define GINTENLIB_PLANE_INCLUDED_FWD_HPP_
+
+/*
+
+ <gintenlib/plane/fwd.hpp>
+
+ ¤¤¤í¤¤¤í¤ÈÀè¹ÔÀë¸À¤¹¤ë¥Ø¥Ã¥À¤Ç¤¹¡£
+
+*/
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ template< typename T >
+ struct basic_angle;
+
+ template< typename T >
+ struct basic_vector;
+
+ template< typename T >
+ struct basic_point;
+
+ template< typename T >
+ struct basic_rect;
+
+ template< typename T >
+ struct basic_quadrangle;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_FWD_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_POINT_HPP_
+#define GINTENLIB_PLANE_INCLUDED_POINT_HPP_
+
+/*
+
+ <gintenlib/plane/point.hpp>
+
+ point ¡§ Æ󼡸µ°ÌÃÖ¥Ù¥¯¥È¥ë
+
+ µ¡Ç½¡§
+ Æ󼡸µ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤òɽ¤¹¥¯¥é¥¹¡£
+ °ÌÃÖ¥Ù¥¯¥È¥ë¤Ê¤Î¤Ç²Ã»»¤Ç¤¤Þ¤»¤ó¡£¼Â¿ôÇܤâ½ÐÍè¤Þ¤»¤ó¡£
+ ¤Ç¤âÁêÂÐ¥Ù¥¯¥È¥ë¡Êvector¡Ë¤ò²Ã»»¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï½ÐÍè¤Þ¤¹¡£
+ ¤Á¤Ê¤ß¤Ëº¹¤ò¼è¤ë¤³¤È¤Ï²Äǽ¤Ç¡¢¤½¤¦¤¹¤ë¤ÈÁêÂÐ¥Ù¥¯¥È¥ë¤ËÊѲ½¤·¤Þ¤¹¡£
+ °ÌÃÖ¥Ù¥¯¥È¥ë¤ÈÁêÂÐ¥Ù¥¯¥È¥ë¤òº®Æ±¤¹¤ë¤È¥Ð¥°¤Î¸µ¤Ë¤Ê¤ë¤Î¤Ç¡¢¤½¤ì¤òËɤ°¤¿¤á¤À¤±¤Î¥¯¥é¥¹¡£
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // point : °ÌÃÖ¥Ù¥¯¥È¥ë
+ template<typename Real>
+ struct basic_point : private boost::additive< basic_point<Real>, basic_vector<Real> >
+ , private boost::equality_comparable< basic_point<Real> >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_point()
+ : x(), y() {}
+
+ basic_point( real_type x_, real_type y_ )
+ : x(x_), y(y_) {}
+
+ template<typename T>
+ basic_point( const basic_point<T>& src )
+ : x(src.x), y(src.y) {}
+
+ template<typename T>
+ explicit basic_point( const basic_vector<T>& src )
+ : x(src.first), y(src.second) {}
+
+ // operator overloads
+ basic_point<Real> operator+=( const basic_vector<Real>& rhs )
+ {
+ x += rhs.x; y += rhs.y;
+ return *this;
+ }
+ basic_point<Real> operator-=( const basic_vector<Real>& rhs )
+ {
+ x -= rhs.x; y -= rhs.y;
+ return *this;
+ }
+ // ¸å¡¢°ÌÃÖ¥Ù¥¯¥È¥ëƱ»Î¤Îº¹Ê¬
+ basic_vector<Real> operator-( const basic_point& rhs ) const
+ {
+ return basic_vector<Real>( x - rhs.x, y - rhs.y );
+ }
+ // ÅùÃÍÈæ³Ó
+ bool operator==( const basic_point& rhs ) const
+ {
+ return ( x == rhs.x ) && ( y == rhs.y );
+ }
+
+ // vector ¤ËÊÑ´¹
+ basic_vector<Real> to_vector() const
+ {
+ return basic_vector<Real>( x, y );
+ }
+
+ };
+ typedef basic_point<double> point;
+
+ // ÃæÅÀ¤òµá¤á¤ë
+ template<typename T>
+ basic_point<T> midpoint( const basic_point<T>& p1, const basic_point<T>& p2 )
+ {
+ return basic_point<T>( (p1.x+p2.x)/2, (p1.y+p2.y)/2 );
+ }
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_POINT_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
+#define GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
+
+/*
+
+ <gintenlib/plane/quadrangle.hpp>
+
+ quadrangle ¡§ Æ󼡸µ¶õ´Ö¾å¤Î»Í³Ñ·Á
+
+ Àë¸À¡§
+ // quadrangle : »Í³Ñ·Á
+ template<typename Real>
+ struct basic_quadrangle
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ // Ãæ¿´ºÂɸ
+ pos_type pos;
+ // ³ÆĺÅÀ¤ÎÃæ¿´ºÂɸ¤«¤é¤Î°ÌÃÖ¥Ù¥¯¥È¥ë
+ vec_type a1, a2, a3, a4;
+
+ basic_quadrangle();
+
+ // ¸¶ÅÀ¤òÃæ¿´¤È¤·¤¿»Í³Ñ·Á¤òÀ½ºî¤¹¤ë
+ basic_quadrangle( const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ );
+
+ // °ÌÃÖ¥Ù¥¯¥È¥ë£´¤Ä¤«¤é»Í³Ñ·Á¤òÀ½ºî¤¹¤ë¡£
+ // Ãæ¿´¤Ï£´ÅÀ¤ÎÊ¿¶Ñ¡¢¤¹¤Ê¤ï¤Á½Å¿´
+ basic_quadrangle( const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ );
+
+ // Á´Í×ÁǤò»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ );
+
+ // Á´Í×ÁǤò°ÌÃÖ¥Ù¥¯¥È¥ë¤Ç»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ );
+
+ template<typename T>
+ basic_quadrangle( const basic_quadrangle<T>& src );
+
+
+ // ³ÆĺÅÀ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤ò»»½Ð
+ pos_type vertex1() const { return pos + a1; }
+ pos_type vertex2() const { return pos + a2; }
+ pos_type vertex3() const { return pos + a3; }
+ pos_type vertex4() const { return pos + a4; }
+
+ // operator[]
+ // ¥¤¥ó¥Æ¥Ã¥¯¥¹¤ËÂбþ¤¹¤ëĺÅÀºÂɸ¤ò»»½Ð
+ pos_type operator[]( std::size_t index ) const;
+ pos_type at( std::size_t index ) const;
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ // ¥á¥ó¥ÐÈǤϼ«¿È¤òÊѹ¹¡¢ friend ÈǤϷë²Ì¤ò½ÐÎÏ¡£
+ basic_quadrangle& shift( const vec_type& d );
+ friend basic_quadrangle shift( const basic_quadrangle& target, const vec_type& d );
+
+ // ĺÅÀ¤Î°ÌÃÖ¤òÊѤ¨¤º¡¢Ãæ¿´¤òÊѹ¹
+ // friend ÈǤϤ¢¤ê¤Þ¤»¤ó¡£
+ basic_quadrangle& move_center( const pos_type& center );
+ basic_quadrangle& move_center( const vec_type& d );
+ // °ú¿ô¤Ê¤·¤À¤È½Å¿´¤Ë»ý¤Ã¤Æ¤¤¤¯
+ basic_quadrangle& move_center();
+
+ // ²óž
+ // rect, vector ¤È¤«¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¡£
+ // Ãæ¿´ºÂɸ¤ò¤ï¤¶¤ï¤¶¸ÄÊ̤ËÀßÄꤷ¤Æ¤¤¤ë¤Î¤Ï¡¢¤³¤Î¤È¤¤Î²óž¼´¤ò·è¤á¤ë¤¿¤á¡£
+ template<typename Angle>
+ basic_quadrangle& rotate( const Angle& theta );
+ basic_quadrangle& rotate( real_type s, real_type c );
+ template<typename Angle>
+ friend basic_quadrangle rotate( const basic_quadrangle& x, const Angle& theta );
+ friend basic_quadrangle rotate( const basic_quadrangle& x, real_type s, real_type c );
+
+ };
+ typedef basic_quadrangle<double> quadrangle;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¶õ´Ö¾å¤Î¡¢ÄºÅÀ¤Î°ÌÃÖ¤ÈÃæ¿´¤Î³ÎÄꤷ¤¿¤ò»Í³Ñ·Á¤òɽ¤¹¥¯¥é¥¹¡£
+ Ê¿¹Ô°ÜÆ°¡¢²óž¤Ê¤É¤¬¹Ô¤¨¤Þ¤¹¡£¤Ä¡¼¤«Ì¾Á°Ä¹¤¤¤è¡£
+
+*/
+
+#include "fwd.hpp"
+#include "vector.hpp"
+#include "point.hpp"
+
+namespace gintenlib
+{
+ namespace plane
+ {
+
+ // quadrangle : »Í³Ñ·Á
+ template<typename Real>
+ struct basic_quadrangle
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ // Ãæ¿´ºÂɸ
+ pos_type pos;
+ // ³ÆĺÅÀ¤ÎÃæ¿´ºÂɸ¤«¤é¤Î°ÌÃÖ¥Ù¥¯¥È¥ë
+ vec_type a1, a2, a3, a4;
+
+ basic_quadrangle()
+ : pos(), a1(), a2(), a3(), a4() {}
+
+ // ¸¶ÅÀ¤òÃæ¿´¤È¤·¤¿»Í³Ñ·Á¤òÀ½ºî¤¹¤ë
+ basic_quadrangle( const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ )
+ : pos(), a1(a1_), a2(a2_), a3(a3_), a4(a4_) {}
+
+ // °ÌÃÖ¥Ù¥¯¥È¥ë£´¤Ä¤«¤é»Í³Ñ·Á¤òÀ½ºî¤¹¤ë¡£
+ // Ãæ¿´¤Ï£´ÅÀ¤ÎÊ¿¶Ñ¡¢¤¹¤Ê¤ï¤Á½Å¿´
+ basic_quadrangle( const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ )
+ {
+ pos = midpoint( midpoint( a1_, a2_ ), midpoint( a3_, a4_ ) );
+
+ a1 = a1_ - pos;
+ a2 = a2_ - pos;
+ a3 = a3_ - pos;
+ a4 = a4_ - pos;
+ }
+
+ // Á´Í×ÁǤò»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const vec_type& a1_, const vec_type& a2_,
+ const vec_type& a3_, const vec_type& a4_ )
+ : pos(pos_), a1(a1_), a2(a2_), a3(a3_), a4(a4_) {}
+
+ // Á´Í×ÁǤò°ÌÃÖ¥Ù¥¯¥È¥ë¤Ç»ØÄꤷ¤Æ¹½ÃÛ
+ basic_quadrangle( const pos_type& pos_, const pos_type& a1_, const pos_type& a2_,
+ const pos_type& a3_, const pos_type& a4_ )
+ : pos(pos_), a1( a1_ - pos ), a2( a2_ - pos ), a3( a3_ - pos ), a4( a4_ - pos ) {}
+
+ template<typename T>
+ basic_quadrangle( const basic_quadrangle<T>& src )
+ : pos(src.pos), a1(src.a1), a2(src.a2), a3(src.a3), a4(src.a4) {}
+
+
+ // ³ÆĺÅÀ¤Î°ÌÃÖ¥Ù¥¯¥È¥ë¤ò»»½Ð
+ pos_type vertex1() const { return pos + a1; }
+ pos_type vertex2() const { return pos + a2; }
+ pos_type vertex3() const { return pos + a3; }
+ pos_type vertex4() const { return pos + a4; }
+
+ // operator[]
+ pos_type operator[]( std::size_t index ) const
+ {
+ using namespace std;
+
+ switch( index )
+ {
+ case 0:
+ return vertex1();
+
+ case 1:
+ return vertex2();
+
+ case 2:
+ return vertex3();
+
+ case 3:
+ return vertex4();
+
+ default:
+ assert( !"should not get here." );
+
+ }
+ }
+ pos_type at( std::size_t index ) const
+ {
+ if( index > size() )
+ {
+ throw std::out_of_range();
+ }
+
+ return operator[](index);
+ }
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ basic_quadrangle& shift( const vec_type& d )
+ {
+ pos += d;
+
+ return *this;
+ }
+ friend basic_quadrangle shift( const basic_quadrangle& target, const vec_type& d )
+ {
+ basic_quadrangle temp = target;
+ return temp.shift(d);
+ }
+
+ // ĺÅÀ¤Î°ÌÃÖ¤òÊѤ¨¤º¡¢Ãæ¿´¤òÊѹ¹
+ basic_quadrangle& move_center( const pos_type& center )
+ {
+ vec_type d = pos - center;
+
+ pos = center;
+ a1 += d;
+ a2 += d;
+ a3 += d;
+ a4 += d;
+
+ return *this;
+ }
+ basic_quadrangle& move_center( const vec_type& d )
+ {
+ pos += d;
+ a1 -= d;
+ a2 -= d;
+ a3 -= d;
+ a4 -= d;
+
+ return *this;
+ }
+ // °ú¿ô¤Ê¤·¤À¤È½Å¿´¤Ë»ý¤Ã¤Æ¤¤¤¯
+ basic_quadrangle& move_center()
+ {
+ basic_quadrangle temp( vertex1(), vertex2(), vertex3(), vertex4() );
+ *this = temp;
+ return *this;
+ }
+
+ // ²óž
+ template<typename Angle>
+ basic_quadrangle& rotate( const Angle& theta )
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(theta), cos(theta) );
+ }
+ basic_quadrangle& rotate( real_type s, real_type c )
+ {
+ a1.rotate( s, c );
+ a2.rotate( s, c );
+ a3.rotate( s, c );
+ a4.rotate( s, c );
+
+ return *this;
+ }
+ template<typename Angle>
+ friend basic_quadrangle rotate( const basic_quadrangle& x, const Angle& theta )
+ {
+ basic_quadrangle temp = x;
+ return temp.rotate(theta);
+ }
+ friend basic_quadrangle rotate( const basic_quadrangle& x, real_type s, real_type c )
+ {
+ basic_quadrangle temp = x;
+ return temp.rotate( s, c );
+ }
+
+ };
+ typedef basic_quadrangle<double> quadrangle;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_QUADRANGLE_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_RECT_HPP_
+#define GINTENLIB_PLANE_INCLUDED_RECT_HPP_
+
+/*
+
+ <gintenlib/plane/rect.hpp>
+
+ rect ¡§ Æ󼡸µ¶õ´Ö¾å¤Î¶ë·Á
+
+ Àë¸À¡§
+ // rect : ¶ë·Á
+ template<typename Real>
+ struct basic_rect
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ real_type x1, y1, x2, y2;
+
+ basic_rect();
+ basic_rect( real_type x1_, real_type y1_, real_type x2_, real_type y2_ );
+
+ template<typename T>
+ basic_rect( const basic_rect<T>& src );
+
+ // operator[]
+ // ĺÅÀ¤ÎºÂɸ¤òÊÖ¤·¤Þ¤¹¡£
+ pos_type operator[]( std::size_t index ) const;
+
+ pos_type at( std::size_t index ) const;
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ // ¤³¤Î¶ë·Á¼«¿È¤ò¥·¥Õ¥È¤µ¤»¤Þ¤¹¡£
+ basic_rect& shift( const vec_type& d );
+ // friend ÈǤϥ³¥Ô¡¼¤·¤Æ¤«¤é¥·¥Õ¥È¤·¤Þ¤¹¡£
+ friend basic_rect shift( const basic_rect& target, const vec_type& d );
+
+ // ²óž
+ // ¤³¤Î¶ë·Á¼«¿È¤ò²óž¤µ¤»¤¿¤¤¤¬¡¢¤½¤¦¤¹¤ë¤È¶ë·Á¤Ç¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¦¤Î¤Ç¡¢
+ // ¤ä¤à¤Ê¤¯»Í³Ñ·Á¤È¤·¤Æ¥³¥Ô¡¼¤·¤Æ¤«¤é²óž¤µ¤»¤Þ¤¹¡£
+ // Angle ÈǤϳÑÅÙ¤«¤é¥µ¥¤¥ó¥³¥µ¥¤¥ó¤òµá¤á¤Æ²óž¡¢
+ // s, c ÈǤϥµ¥¤¥ó¥³¥µ¥¤¥óÃͤ«¤éľÀܲ󞤵¤»¤Þ¤¹¡£
+ template<typename Angle>
+ basic_quadrangle<Real> rotate( const Angle& theta ) const;
+ basic_quadrangle<Real> rotate( real_type s, real_type c ) const;
+ template<typename Angle>
+ friend basic_quadrangle<Real> rotate( const basic_rect& x, const Angle& theta );
+ basic_quadrangle<Real> rotate( const basic_rect& x, real_type s, real_type c );
+
+ };
+ typedef basic_rect<double> rect;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¶õ´Ö¾å¤Î¡¢°ÌÃ֤γÎÄꤷ¤¿¶ë·Á¤òɽ¤¹¥¯¥é¥¹¡£
+ ²óž¤µ¤»¤ë¤È»Í³Ñ·Á¤ËÊѲ½¤¹¤ë°Ê³°¤ÏÉáÄ̤«¤È¡£
+
+*/
+
+#include <cstddef>
+#include <cassert>
+#include <stdexcept>
+
+#include "fwd.hpp"
+#include "vector.hpp"
+#include "point.hpp"
+#include "quadrangle.hpp"
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ // rect : ¶ë·Á
+ template<typename Real>
+ struct basic_rect
+ {
+ typedef Real real_type;
+ typedef basic_point<Real> pos_type;
+ typedef basic_vector<Real> vec_type;
+
+ real_type x1, y1, x2, y2;
+
+ basic_rect()
+ : x1(), y1(), x2(), y2() {}
+
+ basic_rect( real_type x1_, real_type y1_, real_type x2_, real_type y2_ )
+ : x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
+
+ template<typename T>
+ basic_rect( const basic_rect<T>& src )
+ : x1(src.x1), y1(src.y1), x2(src.x2), y2(src.y2) {}
+
+ // operator[]
+ pos_type operator[]( std::size_t index ) const
+ {
+ using namespace std;
+
+ switch( index )
+ {
+ case 0:
+ return pos_type( x1, y1 );
+
+ case 1:
+ return pos_type( x2, y1 );
+
+ case 2:
+ return pos_type( x2, y2 );
+
+ case 3:
+ return pos_type( x1, y2 );
+
+ default:
+ assert( !"should not get here." );
+
+ }
+ }
+ pos_type at( std::size_t index ) const
+ {
+ if( index > size() )
+ {
+ throw std::out_of_range();
+ }
+
+ return operator[](index);
+ }
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ // °ÌÃ֤Υ·¥Õ¥È
+ basic_rect& shift( const vec_type& d )
+ {
+ x1 += d.x;
+ y1 += d.y;
+ x2 += d.x;
+ y2 += d.y;
+
+ return *this;
+ }
+ friend basic_rect shift( const basic_rect& target, const vec_type& d )
+ {
+ basic_rect temp = target;
+ return temp.shift(d);
+ }
+
+ // ²óž
+ template<typename Angle>
+ basic_quadrangle<Real> rotate( const Angle& theta ) const
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(theta), cos(theta) );
+ }
+ basic_quadrangle<Real> rotate( real_type s, real_type c ) const
+ {
+ pos_type center( (x1 + x2) / 2, (y1 + y2) / 2 );
+ real_type w = (x2 - x1) / 2, h = (x2 - x1) / 2;
+ real_type sw = s * w, sh = s * h, cw = c * w, ch = c * h;
+
+ vec_type p1( -cw - sh, -ch + sw ), p2( cw - sh, -ch - sw );
+
+ return basic_quadrangle<Real>( center, p1, p2, -p1, -p2 );
+ }
+ template<typename Angle>
+ friend basic_quadrangle<Real> rotate( const basic_rect& x, const Angle& theta )
+ {
+ return x.rotate(theta);
+ }
+ basic_quadrangle<Real> rotate( const basic_rect& x, real_type s, real_type c )
+ {
+ return x.rotate( s, c );
+ }
+
+ };
+ typedef basic_rect<double> rect;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_RECT_HPP_
--- /dev/null
+#ifndef GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
+#define GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
+
+/*
+
+ <gintenlib/plane/vector.hpp>
+
+ vector ¡§ Æ󼡸µ¥Ù¥¯¥È¥ë
+
+ Àë¸À¡§
+ template< typename Real >
+ struct basic_vector
+ : private boost::equality_comparable< basic_vector<Real> >,
+ private boost::additive< basic_vector<Real> >,
+ private boost::multiplicative< basic_vector<Real>, Real >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_vector();
+ basic_vector( real_type x_, real_type y_ );
+
+ template<typename T>
+ basic_vector( const basic_vector<T>& src );
+
+ template<typename T>
+ basic_vector( const std::pair<T, T>& src );
+
+ // ±é»»»Ò¿½ÅÄêµÁ
+ // ¤½¤ì¤¾¤ì¸«¤¿¤Þ¤ó¤Þ¤Ç¤¹¡£operator+ ¤È¤«¤Ï boost:: operators ¤Ë¤è¤Ã¤Æ³Æ¼ï¼«Æ°ÄêµÁ¤µ¤ì¤Þ¤¹¡£
+ basic_vector& operator+=( const basic_vector& rhs );
+ basic_vector& operator-=( const basic_vector& rhs );
+ basic_vector operator-() const;
+ basic_vector& operator*=( real_type rhs );
+ basic_vector& operator/=( real_type rhs );
+ bool operator==( const basic_vector& rhs ) const;
+
+ // 2-Norm
+ real_type norm() const;
+ friend real_type norm( const basic_vector& target );
+
+ // ÀäÂÐÃÍ
+ real_type absolute() const;
+ friend real_type absolute( const basic_vector& target );
+
+ // Àµµ¬²½
+ // Àµµ¬²½¤·¤¿·ë²Ì¤òÊÖ¤¹¤Î¤Ç¤Ï¤Ê¤¯¡¢¤³¤Î¥Ù¥¯¥È¥ë¼«ÂΤòÀµµ¬²½¤·¤Þ¤¹¡£
+ basic_vector& normalize();
+ // friend ÈǤϥ³¥Ô¡¼¤·¤Æ¤«¤éÀµµ¬²½¤·¤Þ¤¹¡£
+ friend basic_vector normalized( const basic_vector& x );
+
+ // ÊгÑ
+ real_type argument() const;
+ friend real_type argument( const basic_vector& x );
+
+ // ÆâÀÑ
+ real_type dot( const basic_vector& rhs ) const;
+ friend real_type dot( const basic_vector& lhs, const basic_vector& rhs );
+ friend real_type operator*( const basic_vector& lhs, const basic_vector& rhs );
+
+ // ¥í¡¼¥Æ¡¼¥È¡£²óž¤µ¤»¤¿·ë²Ì¤òÊÖ¤¹¤Î¤Ç¤Ï¤Ê¤¯¡¢¤³¤Î¥Ù¥¯¥È¥ë¼«ÂΤò²ó¤·¤Þ¤¹¡£
+ // ³ÑÅÙ»ØÄê¥Ð¡¼¥¸¥ç¥ó¡£¥Æ¥ó¥×¥ì¡¼¥È¤Ê¤Î¤Ï¡¢gintenlib::plane::angle ¤âÅϤ»¤ë¤è¤¦¤Ë¡¢¤Ç¤¹¡£
+ template< typename Angle >
+ basic_vector& rotate( const Angle& angle );
+ // ¥µ¥¤¥ó¤È¥³¥µ¥¤¥ó¤ò»ØÄꤷ¤¿¥Ð¡¼¥¸¥ç¥ó¡£¹â®¤Ç¤¹¡£
+ basic_vector& rotate( real_type s, real_type c );
+
+ // ¾åÆó¤Ä¤Î friend ÈÇ¡£¥³¥Ô¡¼¤·¤Æ¤«¤é²ó¤·¤Þ¤¹¡£
+ template< typename Angle >
+ friend basic_vector rotate( const basic_vector& target, const Angle& angle );
+ friend basic_vector rotate( const basic_vector& target, real_type s, real_type c );
+ };
+ typedef basic_vector<double> vector;
+
+ µ¡Ç½¡§
+ Æ󼡸µ¤ÎÁêÂÐ¥Ù¥¯¥È¥ë¤òɽ¤¹¥¯¥é¥¹¡£
+ ÀäÂÐÃÍ·×»»¡¢Êгѷ׻»¡¢Àµµ¬²½¡¢²óž¤Ê¤É¡¢¤È¤ê¤¢¤¨¤º°ìÄ̤êɬÍפ½¤¦¤Ê¤â¤Î¤Ï·¤¨¤Æ¤¤¤Þ¤¹¡£
+
+*/
+
+#include "fwd.hpp"
+
+#include <cmath>
+#include <utility>
+#include <boost/operators.hpp>
+
+namespace gintenlib
+{
+ namespace plane
+ {
+ template< typename Real >
+ struct basic_vector
+ : private boost::equality_comparable< basic_vector<Real> >,
+ private boost::additive< basic_vector<Real> >,
+ private boost::multiplicative< basic_vector<Real>, Real >
+ {
+ typedef Real real_type;
+ real_type x, y;
+
+ basic_vector()
+ : x(), y() {}
+
+ basic_vector( real_type x_, real_type y_ )
+ : x(x_), y(y_) {}
+
+ template<typename T>
+ basic_vector( const basic_vector<T>& src )
+ : x(src.x), y(src.y) {}
+
+ template<typename T>
+ basic_vector( const std::pair<T, T>& src )
+ : x(src.first), y(src.second) {}
+
+ // ±é»»»Ò¿½ÅÄêµÁ
+ basic_vector& operator+=( const basic_vector& rhs )
+ {
+ x += rhs.x;
+ y += rhs.y;
+
+ return *this;
+ }
+ basic_vector& operator-=( const basic_vector& rhs )
+ {
+ x -= rhs.x;
+ y -= rhs.y;
+
+ return *this;
+ }
+ basic_vector operator-() const
+ {
+ return basic_vector( -x, -y );
+ }
+ basic_vector& operator*=( real_type rhs )
+ {
+ x *= rhs;
+ y *= rhs;
+
+ return *this;
+ }
+ basic_vector& operator/=( real_type rhs )
+ {
+ x /= rhs;
+ y /= rhs;
+
+ return *this;
+ }
+ bool operator==( const basic_vector& rhs ) const
+ {
+ return ( x == rhs.x ) && ( y == rhs.y );
+ }
+
+ // 2-Norm
+ real_type norm() const
+ {
+ return x * x + y * y;
+ }
+ friend real_type norm( const basic_vector& target )
+ {
+ return target.norm();
+ }
+
+ // ÀäÂÐÃÍ
+ real_type absolute() const
+ {
+ return std::sqrt( x * x + y * y );
+ }
+ friend real_type absolute( const basic_vector& target )
+ {
+ return target.absolute();
+ }
+
+ // Àµµ¬²½
+ basic_vector& normalize()
+ {
+ real_type r = absolute();
+
+ if( r == 0 )
+ {
+ x = 1;
+ y = 0;
+ }
+ else
+ {
+ x /= r;
+ y /= r;
+ }
+
+ return *this;
+ }
+ friend basic_vector normalized( const basic_vector& x )
+ {
+ basic_vector temp = x;
+ temp.normalize();
+ return temp;
+ }
+
+ // ÊгÑ
+ real_type argument() const
+ {
+ if( x == 0 && y == 0 )
+ {
+ return 0;
+ }
+ return std::atan2( y, x );
+ }
+ friend real_type argument( const basic_vector& x )
+ {
+ return x.argument();
+ }
+
+ // ÆâÀÑ
+ real_type dot( const basic_vector& rhs ) const
+ {
+ return x * rhs.x + y * rhs.y;
+ }
+ friend real_type dot( const basic_vector& lhs, const basic_vector& rhs )
+ {
+ return lhs.dot(rhs);
+ }
+ friend real_type operator*( const basic_vector& lhs, const basic_vector& rhs )
+ {
+ return lhs.dot(rhs);
+ }
+
+ // ¥í¡¼¥Æ¡¼¥È
+ template< typename Angle >
+ basic_vector& rotate( const Angle& angle )
+ {
+ using std::sin; using std::cos;
+ return rotate( sin(angle), cos(angle) );
+ }
+ basic_vector& rotate( real_type s, real_type c )
+ {
+ real_type sx = s*x, sy = s*y, cx = c*x, cy = c*y;
+
+ x = cx - sy;
+ y = sx + cy;
+
+ return *this;
+ }
+ template< typename Angle >
+ friend basic_vector rotate( const basic_vector& target, const Angle& angle )
+ {
+ basic_vector temp = target;
+ temp.rotate( angle );
+ return temp;
+ }
+ friend basic_vector rotate( const basic_vector& target, real_type s, real_type c )
+ {
+ basic_vector temp = target;
+ temp.rotate( s, c );
+ return temp;
+ }
+ };
+ typedef basic_vector<double> vector;
+
+ } // namespace plane
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_PLANE_INCLUDED_VECTOR_HPP_
--- /dev/null
+#ifndef GINTENLIB_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_
--- /dev/null
+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
--- /dev/null
+#ifndef GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
+#define GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
+
+/*
+
+ <gintenlib/preprocessor/dequote.hpp>
+
+ dequote ¡§ ¥Þ¥¯¥í¤Î°ú¿ô¤Ë¥Æ¥ó¥×¥ì¡¼¥È¤ò»È¤¦¾ì¹ç¤Î¥æ¡¼¥Æ¥£¥ê¥Æ¥£
+
+ Àë¸À¡§
+ namespace gintenlib
+ {
+ namespace detail_
+ {
+ template<typename T>
+ struct dequote_helper{};
+
+ template<typename Arg>
+ struct dequote_helper<void (*)(Arg)>
+ {
+ typedef Arg type;
+ };
+
+ }
+ }
+
+ #define GINTENLIB_DEQUOTE( QUOTED_TYPE ) \
+ ::gintenlib::detail_::dequote_helper<void (*)QUOTED_TYPE>::type
+
+ »ÈÍÑÎ㡧
+ // Îã¤È¤·¤Æ¡¢Í¿¤¨¤é¤ì¤¿·¿¤Ë¤¿¤¤¤·¡¢¤½¤Î·¿Æó¤Ä¤Î¥Ú¥¢¤Î·¿¤òÊÖ¤¹¥Þ¥¯¥í¤òÄêµÁ¤·¤Æ¤ß¤ë
+ // ¥Æ¥ó¥×¥ì¡¼¥È¤Ø¤ÎÊÌ̾ÉÕ¤±¤¬ C++ ɸ½à¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ì¤ÐÉÔÍפǤ¹¤¬¡¢¸½¾õ̵Íý¤Ê¤Î¤Ç
+
+ // ¤Þ¤º¥À¥á¤ÊÎã
+ // #define PAIR_OF( type ) std::pair<type, type>
+ // ¤³¤ì¤À¤È¡¢ PAIR_OF( std::pair<int, double> ) ¤Î¤è¤¦¤Ê
+ // Ê£¿ô¤Î°ú¿ô¤ò»ý¤Ä¥Æ¥ó¥×¥ì¡¼¥È·¿¤ò¡¢¥Þ¥¯¥í¤Î°ú¿ô¤È¤·¤ÆÅϤ¹¤³¤È¤¬½ÐÍè¤Ê¤¤
+ // ¡Ê¥×¥ê¥×¥í¥»¥Ã¥µ¤Ï¥Æ¥ó¥×¥ì¡¼¥È¤Î»°³Ñ³ç¸Ì¤ò̵»ë¤¹¤ë¤¿¤á¡¢Æó°ú¿ô¥Þ¥¯¥í¤È´ª°ã¤¤¤µ¤ì¤ë¡Ë
+
+ // ¤½¤³¤Ç¡¢¤³¤¦½ñ¤¯
+ #define PAIR_OF( quoted_type ) \
+ std::pair< \
+ typename GINTENLIB_DEQUOTE( quoted_type ), \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >
+ // GINTENLIB_DEQUOTE ¤Ï ¤Ê¤ó¤¿¤é::type ¤È¤¤¤¦¤Õ¤¦¤ËŸ³«¤µ¤ì¤ë¤Î¤Ç
+ // ɬÍפ˱þ¤¸¤Æ typename ¥¡¼¥ï¡¼¥É¤òÉÕ¤±¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤
+ // ÂçÂΤξì¹ç¤Ï¤È¤ê¤¢¤¨¤º typename ¤òÉÕ¤±¤ì¤Ð£Ï£Ë
+
+ // »ÈÍѤ¹¤ë¤È¤¤Ï¡¢
+ PAIR_OF(( std::pair<int, double> )) hoge;
+ // ¤³¤Î¤è¤¦¤Ë·¿Ì¾¤òÆó½Å³ç¸Ì¤Ç¤¯¤ë¤à
+
+ ²òÀ⡧
+ ¤³¤Î¥Þ¥¯¥í¤¬²¿¤ò¤·¤Æ¤¤¤ë¤«¤Ï¡¢Îã¤ò¸«¤ì¤Ðʬ¤«¤ë¤È»×¤¦¤Î¤Ç¡¢Ê¬¤«¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+ ´Êñ¤Ë¸À¤¨¤Ð¡¢¡Ö ( ·¿Ì¾ ) ¡×¤È¤¤¤¦¥·¥ó¥Ü¥ëÎó¤ò¼õ¤±¼è¤ê¡¢³ç¸Ì¤ò³°¤¹¥Þ¥¯¥í¤Ç¤¹¡£
+ ¼ÂÁõÊýË¡¤Ç¤¹¤¬¡¢¼Â¤Ï¡Ö ( ¤Ê¤ó¤¿¤é ) ¡×¤Î³ç¸Ì¤òľÀܳ°¤¹ÊýË¡¤Ï¡ÊÃΤꤨ¤ëÈϰϤǤϡ˸ºß¤·¤Ê¤¤¤Î¤Ç¡¢
+ ¡Ö void (*)( ·¿Ì¾ ) ¡×¤È¤¤¤¦É½¸½¤Ëľ¤·¤Æ¡¢´Ø¿ô¤Î°ú¿ô¡¢¤È¤¤¤¦·Á¤Ç·¿Ì¾¤òʬΥ¤·¤Æ¤¤¤Þ¤¹¡£
+ ¤½¤¦¤¤¤¦¼ÂÁõ¤ÎÅÔ¹ç¾å¡¢´Ø¿ô·¿¤ò¥Æ¥ó¥×¥ì¡¼¥È¤Î°ú¿ô¤È¤·¤ÆÆü첽¤Ç¤¤ë¥³¥ó¥Ñ¥¤¥é¤Ç¤·¤«Æ°ºî¤·¤Þ¤»¤ó¡£
+ ¤Þ¤¿¡¢·¿Ì¾¼«¿È¤ËŸ³«¤µ¤ì¤ë¤ï¤±¤Ç¤â¤Ê¤¤¤Î¤Ç¡¢É¬Íפ˱þ¤¸¤Æ typename ½¤¾þ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+*/
+
+namespace gintenlib
+{
+ namespace detail_
+ {
+ template<typename T>
+ struct dequote_helper {};
+
+ template<typename Arg>
+ struct dequote_helper<void (*)(Arg)>
+ {
+ typedef Arg type;
+ };
+
+ // ËÜÂÎ
+ // QUOTED_TYPE ¤Ï ( DEQUOTED_TYPE ) ¤Î·Á¤Ç»ØÄꤵ¤ì¤ë
+ // dequote_helper<void (*)( DEQUOTED_TYPE )>::type ¤Ï DEQUOTED_TYPE ·¿¤È¤Ê¤ë
+ #define GINTENLIB_DEQUOTE( QUOTED_TYPE ) \
+ ::gintenlib::detail_::dequote_helper<void (*)QUOTED_TYPE>::type
+
+ } // namespace detail_
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_PREPROCESSOR_INCLUDED_DEQUOTE_HPP
--- /dev/null
+#ifndef GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
+#define GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
+
+/*
+
+ <gintenlib/preprocessor/enable_if.hpp>
+
+ preprocessor.enable_if ¡§ ¤é¤¯¤Á¤ó enable_if
+
+ Àë¸À¡§
+ #define GINTENLIB_ENABLE_IF (( condition )) ¡Á
+ #define GINTENLIB_DISABLE_IF(( condition )) ¡Á
+
+ »ÈÍÑÎ㡧
+ // d_enable_if.hpp ¤ÎÎã¤ò¤ä¤Ã¤Ä¤±¤ë
+ // using namespace gintenlib; // ¤³¤ó¤Ê¤ÎɬÍפʤ¤
+
+ // °ú¿ô¤ò Target ·¿¤Ø°ÅÌÛÊÑ´¹¤¹¤ë
+ // Ä̾ïÈÇ¡¢Target ¤¬»²¾È·¿¤Ç¤Ê¤±¤ì¤Ð¤³¤Ã¤Á¤¬¸Æ¤Ð¤ì¤ë
+ // ÂèÆó°ú¿ô¤ËÃíÌÜ¡£¤Á¤Ê¤ß¤Ë¤³¤Î°ú¿ô¤Ï¥À¥ß¡¼¤Ê¤Î¤Ç̵»ë¤·¤Æ£Ï£Ë
+ template< typename Target, typename Source >
+ inline Target cast( const Source& src,
+ GINTENLIB_DISABLE_IF(( boost::is_reference<Target> )) )
+ {
+ return src;
+ }
+
+ // »²¾ÈÈÇ
+ template< typename Target, typename Source >
+ inline Target cast( Source& src,
+ GINTENLIB_ENABLE_IF(( boost::is_reference<Target> )) )
+ {
+ return src;
+ }
+
+ // c.f.) d_enable_if.hpp ¤ÎÎã
+ //
+ // // »²¾ÈÈÇ
+ // template< typename Target, typename Source >
+ // inline Target cast( Source& src,
+ // typename d_enable_if< boost::is_reference<Target> >::type = dummy_arg_t() )
+ // {
+ // return src;
+ // }
+ //
+ // Èæ³Ó¤·¤Æ¤ß¤ë¤È¡¢¤É¤ì¤À¤±³Ú¤«Ê¬¤«¤ë¤Ï¤º
+
+ ²òÀ⡧
+ ´Ø¿ô¥ª¡¼¥Ð¡¼¥í¡¼¥ÉÍѤΠenable_if ¤ò¤é¤¯¤Á¤ó¤Ë¤¹¤ë¤¿¤á¤Î¥Þ¥¯¥í¤Ç¤¹¡£
+ ¼ÂºÝ¤Ë¤É¤Î¤è¤¦¤ËŸ³«¤µ¤ì¤Æ¤¤¤ë¤«¤Ï²¼¤ÎÎã¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+ ¤Þ¡¼¿¿ÌÌÌܤ˽ñ¤¤¤Æ¤âÎɤ¤¤Î¤Ç¤¹¤¬¡¢
+ typename gintenlib::d_enable_if< ¤Ê¤ó¤¿¤é, gintenlib::dummy_arg_t >::type
+ = gintenlib::dummy_arg_t()
+ ÀµÄ¾¤³¤ó¤ÊŤ¤¥½¡¼¥¹¥³¡¼¥É¤Ê¤ó¤Æ½ñ¤¤¤Æ¤é¤ì¤Þ¤»¤ó¤«¤é¤Í¡£
+ d_enable_if ¤È dummy_arg_t ¤Î¸ºß°ÕµÁ¤Ï <gintenlib/d_enable_if.hpp> ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ »È¤¤Êý¤Ï¡¢¾å¤ÎÎã¤ÎÄ̤ꡢenable_if ¤Î <> ¤ÎÃæ¤Îµ½Ò¤ò¡ÖÆó½Å³ç¸Ì¤Ç¤¯¤¯¤Ã¤Æ¡×¥Þ¥¯¥í¤ËÅϤ·¤Æ¡¢
+ ´Ø¿ô¤Î°ú¿ô¥ê¥¹¥È¤ÎºÇ¸å¤ËÃÖ¤¤¤Æ¤ª¤¯¤À¤±¡£´Êñ¤Ç¤¹¡£
+ ÉáÄÌ¡¢¤³¤¦¤¤¤¦¡Ö¥á¥¿´Ø¿ô¤ò°ú¿ô¤Ë¼è¤ë¡×¥Þ¥¯¥í¤Ã¤Æ¤Î¤Ï¡¢¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¥ê¥¹¥È¤Î¥«¥ó¥Þ¤¬¼ÙËâ¤ò¤·¤Æ
+ Àµ¾ï¤Ë¥Þ¥¯¥íŸ³«¤µ¤ì¤Ê¤«¤Ã¤¿¤ê¤¹¤ë¤Î¤Ç¤¹¤¬¡¢¤³¤ì¤Ë´Ø¤·¤Æ¤Ïµ¤¤Ë¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+ ¥æ¡¼¥¶Â¦¤ÇÃí°Õ¤¹¤Ù¤¤Ï°ìÅÀ¤Î¤ß¡¢¥Þ¥¯¥í¤Î°ú¿ô¤Ïɬ¤ºÆó½Å³ç¸Ì¤Ç¤¯¤ë¤à¤³¤È¡£
+ ¤½¤³¤Ë¤µ¤¨µ¤¤ò¤Ä¤±¤ì¤Ð´Êñ¤Ë´Ø¿ô¸Æ¤Ó½Ð¤·¤ÎÀÚ¤êÂؤ¨¤¬½ÐÍè¤Þ¤¹¡£ÊØÍø¤Ç¤¹¡£
+
+*/
+
+#include "../d_enable_if.hpp"
+#include "dequote.hpp"
+
+namespace gintenlib
+{
+ // GINTENLIB_DEQUOTE(( TYPE )) ¤Ï¡¢ ¤Ê¤ó¤È¤«<¡Á>::type ¤È¤¤¤¦·Á¤ÇŸ³«¤µ¤ì¤ë
+ // ¤³¤Î type ¤¬ TYPE ·¿¤ËÄêµÁ¤µ¤ì¤ë¤è¤¦¤Ê»Å³Ý¤±¤È¤Ê¤Ã¤Æ¤¤¤ë
+ // ¤è¤Ã¤Æ GINTENLIB_DEQUOTE Á°¤Î typename ¤Ïɬ¿Ü
+ #define GINTENLIB_ENABLE_IF( quoted_type ) \
+ typename ::gintenlib::d_enable_if< \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >::type = ::gintenlib::dummy_arg_t()
+
+ #define GINTENLIB_DISABLE_IF( quoted_type ) \
+ typename ::gintenlib::d_disable_if< \
+ typename GINTENLIB_DEQUOTE( quoted_type ) \
+ >::type = ::gintenlib::dummy_arg_t()
+
+} // namespace gintenlib
+
+
+#endif // #ifndef GINTENLIB_PREPROCESSOR_INCLUDED_ENABLE_IF_HPP
--- /dev/null
+#ifndef GINTENLIB_INCLUDED_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_
} // 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