00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00037 #if !defined( _OESS_1__STDSN__SHPTR_HPP_ )
00038 #define _OESS_1__STDSN__SHPTR_HPP_
00039
00040 #include <memory>
00041
00042 #include <oess_1/defs/h/ex.hpp>
00043
00044 #include <oess_1/stdsn/h/declspec.hpp>
00045
00046 #include <oess_1/stdsn/h/serializable.hpp>
00047 #include <oess_1/stdsn/h/errno.hpp>
00048
00049 namespace oess_1 {
00050
00051 namespace stdsn {
00052
00062 template< class T >
00063 class refcountable_policy_t
00064 : private cpp_util_2::nocopy_t
00065 {
00066 private :
00068 typedef unsigned long ref_count_t;
00069
00071 ref_count_t * m_ref_count;
00072
00074 T * & m_pointer_holder;
00075
00076 public :
00078
00081 explicit refcountable_policy_t( T * & pointer_holder )
00082 : m_ref_count( 0 )
00083 , m_pointer_holder( pointer_holder )
00084 {
00085 m_pointer_holder = 0;
00086 }
00087
00089
00093 refcountable_policy_t(
00094 T * & pointer_holder, T * pointer )
00095 : m_ref_count( 0 )
00096 , m_pointer_holder( pointer_holder )
00097 {
00098 assign( pointer );
00099 }
00100
00106 ~refcountable_policy_t()
00107 {
00108 release();
00109 }
00110
00112
00116 void
00117 assign( T * ptr )
00118 {
00119 release();
00120
00121 if( ptr )
00122 {
00123 m_ref_count = new ref_count_t( 1 );
00124 m_pointer_holder = ptr;
00125 }
00126 }
00127
00129
00134 void
00135 reassign()
00136 {
00137
00138 if( m_ref_count )
00139 OESS_THROW_PHYSIC(
00140 err::c_invalid_policy_state_for_reassignment,
00141 "reassignment when m_ref_count != null!" )
00142
00143 m_ref_count = new ref_count_t( 1 );
00144 }
00145
00147
00149 void
00150 link(
00153 const refcountable_policy_t< T > & owner_policy )
00154 {
00155 if( &owner_policy != this )
00156 {
00157 release();
00158
00159 if( 0 != ( m_ref_count = owner_policy.m_ref_count ) )
00160 {
00161 ++( *m_ref_count );
00162 m_pointer_holder = owner_policy.m_pointer_holder;
00163 }
00164 }
00165 }
00166
00168
00174 std::auto_ptr< T >
00175 release()
00176 {
00177 std::auto_ptr< T > result;
00178 if( m_ref_count )
00179 {
00180 if( 0 == ( --(*m_ref_count) ) )
00181 {
00182 ref_count_t * to_be_destroyed = m_ref_count;
00183 m_ref_count = 0;
00184
00185 delete to_be_destroyed;
00186
00187 result = std::auto_ptr< T >( m_pointer_holder );
00188 m_pointer_holder = 0;
00189 }
00190 else
00191
00192 m_ref_count = 0;
00193 }
00194
00195 return result;
00196 }
00197 };
00198
00220 template< class T >
00221 class cloneable_policy_t
00222 : private cpp_util_2::nocopy_t
00223 {
00224 private :
00226 T * & m_pointer_holder;
00227
00228 public :
00230 explicit cloneable_policy_t( T * & pointer_holder )
00231 : m_pointer_holder( pointer_holder )
00232 {
00233 m_pointer_holder = 0;
00234 }
00235
00237
00241 cloneable_policy_t(
00242 T * & pointer_holder, T * pointer )
00243 : m_pointer_holder( pointer_holder )
00244 {
00245 m_pointer_holder = 0;
00246 assign( pointer );
00247 }
00248
00254 ~cloneable_policy_t()
00255 {
00256 release();
00257 }
00258
00260
00264 void
00265 assign( T * ptr )
00266 {
00267 release();
00268
00269 m_pointer_holder = ptr;
00270 }
00271
00273
00282 void
00283 reassign()
00284 {
00285 }
00286
00288
00292 void
00293 link(
00296 const cloneable_policy_t< T > & owner_policy )
00297 {
00298 if( &owner_policy != this )
00299 {
00300 release();
00301
00302 if( owner_policy.m_pointer_holder )
00303 {
00304 std::auto_ptr< T > clone(
00305 owner_policy.m_pointer_holder->clone() );
00306 m_pointer_holder = clone.release();
00307 }
00308 }
00309 }
00310
00312
00316 std::auto_ptr< T >
00317 release()
00318 {
00319 std::auto_ptr< T > result( m_pointer_holder );
00320 m_pointer_holder = 0;
00321
00322 return result;
00323 }
00324 };
00325
00334 template< class T >
00335 struct shptr_type_tag {};
00336
00353 template<
00354 class T,
00355 class Own_policy = refcountable_policy_t< T > >
00356 class shptr_skeleton_t
00357 : public oess_1::stdsn::serializable_t
00358 {
00359 typedef shptr_skeleton_t< T, Own_policy > self_type_t;
00360
00361 protected :
00363 T * m_ptr;
00364
00365 private :
00367 Own_policy m_own_policy;
00368
00369 public :
00371
00374 shptr_skeleton_t()
00375 : m_ptr( 0 )
00376 , m_own_policy( m_ptr )
00377 {}
00378
00380 shptr_skeleton_t(
00384 T * ptr )
00385 : m_ptr( 0 )
00386 , m_own_policy( m_ptr, ptr )
00387 {}
00388
00390 shptr_skeleton_t(
00391 const self_type_t & o )
00392 : m_ptr( 0 )
00393 , m_own_policy( m_ptr )
00394 {
00395 (*this) = o;
00396 }
00397 virtual ~shptr_skeleton_t()
00398 {}
00399
00401 self_type_t &
00402 operator=(
00403 const self_type_t & o )
00404 {
00405 m_own_policy.link( o.m_own_policy );
00406 return *this;
00407 }
00408
00410
00411 virtual void
00412 oess_pack( oess_1::stdsn::oent_t & writter ) const = 0;
00413
00414 virtual void
00415 oess_unpack( oess_1::stdsn::ient_t & reader ) = 0;
00416
00417 virtual void *
00418 oess_cast( const std::string & type_name ) = 0;
00419
00420 virtual const std::string &
00421 oess_type_name() const = 0;
00422
00423 virtual const std::string &
00424 oess_scheme() const = 0;
00425
00426 virtual void
00427 oess_get_subclass_extension_path(
00428 oess_1::stdsn::subclass_extension_path_t & path,
00429 const std::string & terminator ) const = 0;
00433
00434
00441 template< class Y >
00442 Y *
00443 cast_to( const shptr_type_tag< Y > & )
00444 {
00445 typedef typename Y::oess_serializer_t serializer_t;
00446 if( m_ptr )
00447 {
00448 Y * p = reinterpret_cast< Y * >(
00449 m_ptr->oess_cast( serializer_t::type_name() ) );
00450 if( !p )
00451 OESS_THROW_LOGIC( err::c_cast_failed,
00452 "unable cast from '" << m_ptr->oess_type_name()
00453 << "' to '" << serializer_t::type_name() )
00454 return p;
00455 }
00456
00457 return 0;
00458 }
00459
00461
00468 template< class Y >
00469 const Y *
00470 cast_to( const shptr_type_tag< Y > & ) const
00471 {
00472 typedef typename Y::oess_serializer_t serializer_t;
00473 if( m_ptr )
00474 {
00475 const Y * p = reinterpret_cast< const Y * >(
00476 m_ptr->oess_cast( serializer_t::type_name() ) );
00477 if( !p )
00478 OESS_THROW_LOGIC( err::c_cast_failed,
00479 "unable cast from '" << m_ptr->oess_type_name()
00480 << "' to '" << serializer_t::type_name() )
00481 return p;
00482 }
00483
00484 return 0;
00485 }
00488
00489
00490
00491
00496 void *
00497 cast_to( const std::string & type_name )
00498 {
00499 if( m_ptr )
00500 return m_ptr->oess_cast( type_name );
00501 return 0;
00502 }
00503
00505
00510 const void *
00511 cast_to( const std::string & type_name ) const
00512 {
00513 if( m_ptr )
00514 return m_ptr->oess_cast( type_name );
00515 return 0;
00516 }
00517
00519
00520
00529 void
00530 destroy()
00531 {
00532 m_own_policy.release();
00533 }
00534
00535 protected :
00540 virtual void
00541 oess_pre_unpack()
00542 {
00543
00544
00545
00546 destroy();
00547 }
00548
00553 virtual void
00554 oess_post_unpack()
00555 {
00556 m_own_policy.reassign();
00557 }
00558
00561 Own_policy &
00562 own_policy()
00563 {
00564 return m_own_policy;
00565 }
00566
00567 const Own_policy &
00568 own_policy() const
00569 {
00570 return m_own_policy;
00571 }
00573 };
00574
00575
00576
00577
00578
00616 class OESS_1__STDSN__TYPE shptr_t
00617 : public shptr_skeleton_t< oess_1::stdsn::serializable_t >
00618 {
00619 typedef shptr_skeleton_t< oess_1::stdsn::serializable_t > base_type_t;
00620 OESS_SERIALIZER_EX( shptr_t, OESS_1__STDSN__TYPE )
00621 public :
00623
00626 shptr_t();
00628 shptr_t(
00632 serializable_t * ptr );
00634 shptr_t(
00635 const shptr_t & o );
00636 virtual ~shptr_t();
00637
00639
00643 shptr_t &
00644 operator=( const shptr_t & o );
00645
00646 protected :
00649
00650
00657 virtual void
00658 oess_shptr_assign(
00659 const shptr_t & o );
00660
00662
00676 void
00677 oess_reset(
00679 serializable_t * ptr = 0 );
00681 };
00682
00684
00882 #define OESS_1_SHPTR_IFACE(shptr_type, referred_type, base_type) \
00883 private : \
00884 typedef base_type base_type_typedef__; \
00885 typedef base_type base_type_t; \
00886 public : \
00887 shptr_type() {} \
00888 shptr_type( referred_type * p ) : base_type_typedef__( p ) {} \
00889 shptr_type( const shptr_type & o ) : base_type_typedef__( o ) {} \
00890 virtual ~shptr_type() {} \
00891 shptr_type & \
00892 operator=( const shptr_type & o ) \
00893 { base_type_typedef__::operator=( o ); return *this; } \
00894 referred_type * \
00895 get() { return cast_to( oess_1::stdsn::shptr_type_tag< referred_type >() ); } \
00896 const referred_type * \
00897 get() const { return cast_to( oess_1::stdsn::shptr_type_tag< referred_type >() ); } \
00898 referred_type * \
00899 operator->() { return get(); } \
00900 const referred_type * \
00901 operator->() const { return get(); } \
00902 referred_type & \
00903 operator*() { return *get(); } \
00904 const referred_type & \
00905 operator*() const { return *get(); } \
00906 private :
00907
00908 }
00909
00910 }
00911
00912 #endif