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 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00047 #ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES
00048 #define COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES
00049 
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES_MAJOR       6
00052 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES_MINOR       1
00053 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES_REVISION    6
00054 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES_EDIT        52
00055 #endif 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 #ifndef COMSTL_INCL_COMSTL_H_COMSTL
00072 # include <comstl/comstl.h>
00073 #endif 
00074 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00075 # include <stlsoft/util/std/iterator_helper.hpp>
00076 #endif 
00077 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00078 # ifndef COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
00079 #  include <comstl/error/exceptions.hpp>
00080 # endif 
00081 #endif 
00082 
00083 
00084 
00085 
00086 
00087 #ifndef _COMSTL_NO_NAMESPACE
00088 # if defined(_STLSOFT_NO_NAMESPACE) || \
00089      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00090 
00091 namespace comstl
00092 {
00093 # else
00094 
00095 
00096 namespace stlsoft
00097 {
00098 
00099 namespace comstl_project
00100 {
00101 
00102 # endif 
00103 #endif 
00104 
00105 
00106 
00107 
00108 
00109 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00110 
00115 
00116 class clone_failure
00117     : public com_exception
00118 {
00121 public:
00123     typedef com_exception       parent_class_type;
00125     typedef clone_failure       class_type;
00127 
00130 public:
00132     ss_explicit_k clone_failure(HRESULT hr)
00133         : parent_class_type(hr)
00134     {}
00136 
00139 public:
00141 #if defined(STLSOFT_COMPILER_IS_DMC)
00142     char const  *what() const throw()
00143 #else 
00144     char const  *what() const stlsoft_throw_0()
00145 #endif 
00146     {
00147         return "Request to clone enumerator failed";
00148     }
00150 
00153 private:
00154     class_type& operator =(class_type const&);
00156 };
00157 
00158 #endif 
00159 
00160 
00166 struct noncloneable_enumerator_tag
00167 {};
00168 
00174 struct cloneable_enumerator_tag
00175 {};
00176 
00183 struct repeatable_enumerator_tag
00184     : public cloneable_enumerator_tag
00185 {};
00186 
00187 
00188 
00195 template<ss_typename_param_k I>
00196 struct input_cloning_policy
00197     : public noncloneable_enumerator_tag
00198 {
00199 public:
00200     typedef I                                       interface_type;
00201     typedef interface_type*                         value_type;
00202     typedef comstl_ns_qual_std(input_iterator_tag)  iterator_tag_type;
00203 
00204 public:
00208     static interface_type *get_working_instance(interface_type *root)
00209     {
00210         COMSTL_ASSERT(NULL != root);
00211 
00212         root->AddRef();
00213 
00214         return root;
00215     }
00216 
00218     static interface_type *share(interface_type *src)
00219     {
00220         COMSTL_ASSERT(NULL != src);
00221 
00222         src->AddRef();
00223 
00224         return src;
00225     }
00226     static cs_bool_t clone(interface_type *src, interface_type **pdest)
00227     {
00228         COMSTL_ASSERT(NULL != src);
00229         COMSTL_ASSERT(NULL != pdest);
00230         STLSOFT_SUPPRESS_UNUSED(src);
00231 
00232         *pdest = NULL;
00233 
00234         return false;
00235     }
00236 };
00237 
00244 template<ss_typename_param_k I>
00245 struct cloneable_cloning_policy
00246     : public cloneable_enumerator_tag
00247 {
00248 public:
00249     typedef I                                       interface_type;
00250     typedef interface_type*                         value_type;
00251     typedef comstl_ns_qual_std(input_iterator_tag)  iterator_tag_type;
00252 
00253 public:
00258     static interface_type *get_working_instance(interface_type *root)
00259     {
00260         COMSTL_ASSERT(NULL != root);
00261 
00262         interface_type  *ret;
00263         HRESULT         hr  =   const_cast<interface_type*>(root)->Clone(&ret);
00264 
00265         if(FAILED(hr))
00266         {
00267             ret = NULL;
00268         }
00269 
00270         return ret;
00271     }
00272 
00273     static interface_type *share(interface_type *src)
00274     {
00275         COMSTL_ASSERT(NULL != src);
00276 
00277         interface_type  *ret;
00278         HRESULT         hr  =   const_cast<interface_type*>(src)->Clone(&ret);
00279 
00280         if(FAILED(hr))
00281         {
00282 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00283             STLSOFT_THROW_X(clone_failure(hr));
00284 #else 
00285             ret = NULL;
00286 #endif 
00287         }
00288 
00289         return ret;
00290     }
00291     static cs_bool_t clone(interface_type *src, interface_type **pdest)
00292     {
00293         COMSTL_ASSERT(NULL != src);
00294         COMSTL_ASSERT(NULL != pdest);
00295 
00296         *pdest = share(src);
00297 
00298 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00299         COMSTL_ASSERT(NULL != *pdest);
00300 
00301         return true;
00302 #else 
00303         return NULL != *pdest;
00304 #endif 
00305     }
00306 };
00307 
00314 template<ss_typename_param_k I>
00315 struct forward_cloning_policy
00316     : public repeatable_enumerator_tag
00317 {
00318 public:
00319     typedef I                                           interface_type;
00320     typedef interface_type*                             value_type;
00321     typedef comstl_ns_qual_std(forward_iterator_tag)    iterator_tag_type;
00322 
00323 public:
00329     static interface_type *get_working_instance(interface_type *root)
00330     {
00331         COMSTL_ASSERT(NULL != root);
00332 
00333         interface_type  *ret;
00334         HRESULT         hr  =   const_cast<interface_type*>(root)->Clone(&ret);
00335 
00336         if(FAILED(hr))
00337         {
00338 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00339             STLSOFT_THROW_X(clone_failure(hr));
00340 #else 
00341             ret = NULL;
00342 #endif 
00343         }
00344 
00345         return ret;
00346     }
00347 
00349     static interface_type *share(interface_type *src)
00350     {
00351         COMSTL_ASSERT(NULL != src);
00352 
00353         interface_type  *ret;
00354         HRESULT         hr  =   const_cast<interface_type*>(src)->Clone(&ret);
00355 
00356         if(FAILED(hr))
00357         {
00358 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00359             STLSOFT_THROW_X(clone_failure(hr));
00360 #else 
00361             ret = NULL;
00362 #endif 
00363         }
00364 
00365         return ret;
00366     }
00367     static cs_bool_t clone(interface_type *src, interface_type **pdest)
00368     {
00369         COMSTL_ASSERT(NULL != src);
00370         COMSTL_ASSERT(NULL != pdest);
00371 
00372         *pdest = share(src);
00373 
00374 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00375         COMSTL_ASSERT(NULL != *pdest);
00376 
00377         return true;
00378 #else 
00379         return NULL != *pdest;
00380 #endif 
00381     }
00382 };
00383 
00390 template <ss_typename_param_k P>
00391 struct value_policy_adaptor
00392     : public P
00393 {
00394 public:
00395     typedef ss_typename_type_k P::value_type    value_type;
00396 
00397 public:
00399     struct init_element
00400     {
00402         void operator ()(value_type &v) const
00403         {
00404             P::init(&v);
00405         }
00406     };
00408     struct copy_element
00409     {
00411         void operator ()(value_type &dest, value_type const& src) const
00412         {
00413             P::copy(&dest, &src);
00414         }
00415     };
00417     struct clear_element
00418     {
00420         void operator ()(value_type &v) const
00421         {
00422             P::clear(&v);
00423         }
00424     };
00425 };
00426 
00433 template <ss_typename_param_k P>
00434 struct policy_adaptor
00435     : public value_policy_adaptor<P>
00436 {
00437 public:
00438     typedef ss_typename_type_k P::value_type    value_type;
00439 };
00440 
00447 template <ss_typename_param_k CI>
00448 struct new_enum_property_policy
00449 {
00450 public:
00451     typedef CI          collection_interface;
00452 
00453 public:
00454     static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
00455     {
00456         COMSTL_ASSERT(NULL != pcoll);
00457         COMSTL_ASSERT(NULL != ppunkEnum);
00458 
00459         
00460         
00461         
00462         
00463         
00464         
00465         
00466         
00467         
00468         
00469         return pcoll->get__NewEnum(ppunkEnum);
00470     }
00471 };
00472 
00479 template <ss_typename_param_k CI>
00480 struct new_enum_method_policy
00481 {
00482 public:
00483     typedef CI          collection_interface;
00484 
00485 public:
00486     static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
00487     {
00488         COMSTL_ASSERT(NULL != pcoll);
00489         COMSTL_ASSERT(NULL != ppunkEnum);
00490 
00491         return pcoll->_NewEnum(ppunkEnum);
00492     }
00493 };
00494 
00501 template <ss_typename_param_k CI>
00502 struct new_enum_by_dispid_policy
00503 {
00504 public:
00505     typedef CI          collection_interface;
00506 
00507 public:
00508     static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
00509     {
00510         COMSTL_ASSERT(NULL != pcoll);
00511         COMSTL_ASSERT(NULL != ppunkEnum);
00512 
00513         LPDISPATCH  pdisp;
00514         HRESULT     hr  =   pcoll->QueryInterface(IID_IDispatch, reinterpret_cast<void**>(&pdisp));
00515 
00516         if(SUCCEEDED(hr))
00517         {
00518             DISPPARAMS  params;
00519             UINT        argErrIndex;
00520             VARIANT     result;
00521 
00522             ::memset(¶ms, 0, sizeof(params));
00523             ::VariantInit(&result);
00524 
00525             hr = pdisp->Invoke( DISPID_NEWENUM
00526                             ,   IID_NULL
00527                             ,   LOCALE_USER_DEFAULT
00528                             ,   DISPATCH_METHOD | DISPATCH_PROPERTYGET
00529                             ,   ¶ms
00530                             ,   &result
00531                             ,   NULL
00532                             ,   &argErrIndex);
00533 
00534             pdisp->Release();
00535 
00536             if(SUCCEEDED(hr))
00537             {
00538                 hr = ::VariantChangeType(&result, &result, 0, VT_UNKNOWN);
00539 
00540                 if(SUCCEEDED(hr))
00541                 {
00542                     if(NULL == result.punkVal)
00543                     {
00544                         hr = E_UNEXPECTED;
00545                     }
00546                     else
00547                     {
00548                         *ppunkEnum = result.punkVal;
00549 
00550                         (*ppunkEnum)->AddRef();
00551                     }
00552                 }
00553 
00554                 ::VariantClear(&result);
00555             }
00556         }
00557 
00558         return hr;
00559     }
00560 };
00561 
00562 
00563 
00564 #ifndef _COMSTL_NO_NAMESPACE
00565 # if defined(_STLSOFT_NO_NAMESPACE) || \
00566      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00567 } 
00568 # else
00569 } 
00570 } 
00571 # endif 
00572 #endif 
00573 
00574 
00575 
00576 #endif 
00577 
00578