STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

comstl_interface_cast.h

Go to the documentation of this file.
00001 /* 
00002  * File:        comstl_interface_cast.h
00003  *
00004  * Purpose:     Safe interface casting functions.
00005  *
00006  * Created:
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef COMSTL_INCL_H_COMSTL_INTERFACE_CAST
00046 #define COMSTL_INCL_H_COMSTL_INTERFACE_CAST
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define COMSTL_VER_H_COMSTL_INTERFACE_CAST_MAJOR       2
00050 # define COMSTL_VER_H_COMSTL_INTERFACE_CAST_MINOR       0
00051 # define COMSTL_VER_H_COMSTL_INTERFACE_CAST_REVISION    1
00052 # define COMSTL_VER_H_COMSTL_INTERFACE_CAST_EDIT        61
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Compatibility
00057  */
00058 
00059 /*
00060 [Incompatibilies-start]
00061 __STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
00062 [Incompatibilies-end]
00063  */
00064 
00065 /* 
00066  * Includes
00067  */
00068 
00069 #ifndef COMSTL_INCL_H_COMSTL
00070 # include "comstl.h"                    // Include the COMSTL root header
00071 #endif /* !COMSTL_INCL_H_COMSTL */
00072 
00073 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00074     _MSC_VER < 1200
00075 # error comstl_interface_cast.h is not compatible with Visual C++ 5.0 or earlier
00076 #endif /* _MSC_VER < 1200 */
00077 
00078 #ifndef COMSTL_INCL_H_COMSTL_REFCOUNT_FUNCTIONS
00079 # include "comstl_refcount_functions.h" // safe_addref, safe_release
00080 #endif /* !COMSTL_INCL_H_COMSTL_REFCOUNT_FUNCTIONS */
00081 #ifndef COMSTL_INCL_H_COMSTL_INTERFACE_TRAITS
00082 # include "comstl_interface_traits.h"   // Include IID_traits
00083 #endif /* !COMSTL_INCL_H_COMSTL_INTERFACE_TRAITS */
00084 #ifndef COMSTL_INCL_H_COMSTL_BAD_INTERFACE_CAST
00085 # include "comstl_bad_interface_cast.h" // bad_interface_cast
00086 #endif /* !COMSTL_INCL_H_COMSTL_BAD_INTERFACE_CAST */
00087 #ifndef STLSOFT_INCL_H_STLSOFT_OPERATOR_BOOL
00088 # include "stlsoft_operator_bool.h"     // operator_bool_generator
00089 #endif /* !STLSOFT_INCL_H_STLSOFT_OPERATOR_BOOL */
00090 
00091 /* 
00092  * Namespace
00093  *
00094  * The COMSTL components are contained within the comstl namespace. This is
00095  * actually an alias for stlsoft::comstl_project,
00096  *
00097  * The definition matrix is as follows:
00098  *
00099  * _STLSOFT_NO_NAMESPACE    _COMSTL_NO_NAMESPACE    comstl definition
00100  * ---------------------    --------------------    -----------------
00101  *  not defined              not defined             = stlsoft::comstl_project
00102  *  not defined              defined                 not defined
00103  *  defined                  not defined             comstl
00104  *  defined                  defined                 not defined
00105  *
00106  */
00107 
00108 #ifndef _COMSTL_NO_NAMESPACE
00109 # if defined(_STLSOFT_NO_NAMESPACE) || \
00110      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00111 /* There is no stlsoft namespace, so must define ::comstl */
00112 namespace comstl
00113 {
00114 # else
00115 /* Define stlsoft::comstl_project */
00116 
00117 namespace stlsoft
00118 {
00119 
00120 namespace comstl_project
00121 {
00122 
00123 # endif /* _STLSOFT_NO_NAMESPACE */
00124 #endif /* !_COMSTL_NO_NAMESPACE */
00125 
00126 /* 
00127 
00132 
00133 /* 
00134  * Functions
00135  */
00136 
00137 // This helper converts from an interface pointer to itself.
00138 //
00139 // It explicitly takes and returns pointer so that it disambiguates from any
00140 // overload that takes an interface wrapper instance by value/reference.
00141 template <ss_typename_param_k I>
00142 inline I *simple_interface_cast(I *pi)
00143 {
00144     return pi;
00145 }
00146 
00147 /* 
00148  * Functionals
00149  */
00150 
00152 struct ignore_interface_cast_exception
00153 {
00154 public:
00156     struct thrown_type
00157     {
00158     };
00159 
00160 public:
00165     void operator ()(HRESULT hr, REFIID riid) comstl_throw_0()
00166     {
00167         STLSOFT_SUPPRESS_UNUSED(hr);
00168         STLSOFT_SUPPRESS_UNUSED(riid);
00169 
00170         // Do nothing
00171     }
00172 };
00173 
00175 struct throw_bad_interface_cast_exception
00176 {
00177 public:
00179     typedef bad_interface_cast  thrown_type;
00180 
00181 public:
00186     void operator ()(HRESULT hr, REFIID riid) comstl_throw_1(bad_interface_cast)
00187     {
00188         throw bad_interface_cast(riid, hr);
00189     }
00190 };
00191 
00193 template <ss_typename_param_k I>
00194 struct noaddref_release
00195 {
00196 public:
00200     void operator ()(I pi)
00201     {
00202         release(pi);
00203     }
00204 };
00205 
00207 template <ss_typename_param_k I>
00208 struct addref_release
00209 {
00210 public:
00214     void operator ()(I pi)
00215     {
00216         STLSOFT_SUPPRESS_UNUSED(pi);
00217     }
00218 };
00219 
00220 /* 
00221  * Raw-pointer safety
00222  *
00223  * Alas this requires partial template specialisation, so is not available in
00224  * all environments.
00225  */
00226 
00227 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00228 
00232 template <ss_typename_param_k I>
00233 struct interface_pointer_traits;
00234 
00236 template <ss_typename_param_k I>
00237 struct interface_pointer_traits<I*>
00238 {
00239     typedef I   interface_type;
00240 };
00241 
00243 template <ss_typename_param_k I>
00244 interface protect_refcount
00245     : public I
00246 {
00247 private:
00248     STDMETHOD_(ULONG, AddRef)()
00249     {
00250         I   *pi = static_cast<I*>(this);
00251 
00252         return pi->AddRef();
00253     }
00254     STDMETHOD_(ULONG, Release)()
00255     {
00256         I   *pi = static_cast<I*>(this);
00257 
00258         return pi->Release();
00259     }
00260 };
00261 
00262 #endif /* __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
00263 
00264 /* 
00265  * Classes
00266  */
00267 
00275 template<   ss_typename_param_k I
00276         ,   ss_typename_param_k R
00277         ,   ss_typename_param_k X
00278         >
00279 class interface_cast_base
00280 {
00281 public:
00283     typedef I                                                               interface_pointer_type;
00284 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00285 
00286     typedef ss_typename_type_k interface_pointer_traits<I>::interface_type  interface_type;
00287 #endif /* __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
00288 
00289     typedef R                                                               release_type;
00291     typedef X                                                               exception_policy_type;
00293     typedef ss_typename_type_k exception_policy_type::thrown_type           thrown_type;
00295     typedef interface_cast_base<I, R, X>                                    class_type;
00296 
00297 // Construction
00298 protected:
00300 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00301     template <ss_typename_param_k J>
00302     ss_explicit_k interface_cast_base(J &j)
00303         : m_pi(do_cast(simple_interface_cast(j)))
00304     {}
00305 #else
00306     ss_explicit_k interface_cast_base(LPUNKNOWN punk)
00307         : m_pi(do_cast(punk))
00308     {}
00309 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00310 
00312     ss_explicit_k interface_cast_base(interface_pointer_type pi)
00313         : m_pi(pi)
00314     {
00315         addref(m_pi);
00316     }
00317 
00318 protected:
00320     ~interface_cast_base() comstl_throw_0()
00321     {
00322         if(NULL != m_pi)
00323         {
00324             release_type()(m_pi);
00325         }
00326     }
00327 
00328 // Implementation
00329 protected:
00335     static interface_pointer_type do_cast(LPUNKNOWN punk) comstl_throw_1(thrown_type)
00336     {
00337         interface_pointer_type  pi;
00338 
00339         if(NULL == punk)
00340         {
00341             pi = NULL;
00342         }
00343         else
00344         {
00345             REFIID  iid =   IID_traits<interface_pointer_type>().iid();
00346             HRESULT hr  =   punk->QueryInterface(iid, reinterpret_cast<void**>(&pi));
00347 
00348             if(FAILED(hr))
00349             {
00350                 exception_policy_type()(hr, iid);
00351 
00352                 pi = NULL;
00353             }
00354         }
00355 
00356         return pi;
00357     }
00358 
00360     interface_pointer_type const &get_pointer_()
00361     {
00362         return m_pi;
00363     }
00364 
00366     interface_pointer_type get_pointer_() const
00367     {
00368         return m_pi;
00369     }
00370 
00371 // Members
00372 private:
00373     interface_pointer_type const    m_pi;
00374 
00375 // Not to be implemented
00376 public:
00377     interface_cast_base(class_type const &rhs);
00378     class_type const &operator =(class_type const &rhs);
00379 };
00380 
00381 
00388 template<   ss_typename_param_k I
00389         ,   ss_typename_param_k X = throw_bad_interface_cast_exception
00390         >
00391 class interface_cast_noaddref
00392     : protected interface_cast_base<I, noaddref_release<I>, X>
00393 {
00394 private:
00395     typedef interface_cast_base<I, noaddref_release<I>, X>                  parent_class_type;
00396 public:
00398     typedef interface_cast_noaddref<I, X>                                   class_type;
00400     typedef ss_typename_type_k parent_class_type::interface_pointer_type    interface_pointer_type;
00401 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00402 
00403     typedef ss_typename_type_k parent_class_type::interface_type            interface_type;
00404     typedef protect_refcount<interface_type>                                *protected_interface_pointer_type;
00405 #else
00406     typedef interface_pointer_type                                          protected_interface_pointer_type;
00407 #endif // __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00408 
00409 // Construction
00410 public:
00412 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00413     template <ss_typename_param_k J>
00414     ss_explicit_k interface_cast_noaddref(J &j)
00415         : parent_class_type(j)
00416     {}
00417 #else
00418     ss_explicit_k interface_cast_noaddref(LPUNKNOWN punk)
00419         : parent_class_type(punk)
00420     {}
00421 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00422 
00424     ss_explicit_k interface_cast_noaddref(interface_pointer_type pi)
00425         : parent_class_type(pi)
00426     {}
00427 
00428 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00429     ~interface_cast_noaddref() comstl_throw_0()
00430     {} // We need to provide this to persuade VC6 to call the parent class dtor
00431 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00432 
00433 // Accessors
00434 public:
00436     protected_interface_pointer_type operator -> () const
00437     {
00438         comstl_message_assert("Attempting to dereference null pointer. Exception model should not be null", NULL != get_pointer_());
00439 
00440         return static_cast<protected_interface_pointer_type>(get_pointer_());
00441     }
00442 
00443 // Not to be implemented
00444 private:
00445     interface_cast_noaddref(class_type const &rhs);
00446     class_type const &operator =(class_type const &rhs);
00447 
00448     // These are defined to placate Borland C/C++
00449     void *operator new(cs_size_t /* si */) { return 0; }
00450     void operator delete(void * /* pv */) {}
00451 };
00452 
00459 template<   ss_typename_param_k I
00460         ,   ss_typename_param_k X = ignore_interface_cast_exception
00461         >
00462 class interface_cast_addref
00463     : protected interface_cast_base<I, addref_release<I>, X>
00464 {
00465 private:
00466     typedef interface_cast_base<I, addref_release<I>, X>                    parent_class_type;
00467 public:
00469     typedef interface_cast_addref<I, X>                                     class_type;
00471     typedef ss_typename_type_k parent_class_type::interface_pointer_type    interface_pointer_type;
00472 
00473 // Construction
00474 public:
00476 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00477     template <ss_typename_param_k J>
00478     ss_explicit_k interface_cast_addref(J j)
00479         : parent_class_type(j)
00480     {}
00481 #else
00482     ss_explicit_k interface_cast_addref(LPUNKNOWN punk)
00483         : parent_class_type(punk)
00484     {}
00485 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00486 
00488     ss_explicit_k interface_cast_addref(interface_pointer_type pi)
00489         : parent_class_type(pi)
00490     {}
00491 
00492 // Accessors
00493 public:
00495     operator interface_pointer_type ()
00496     {
00497         return get_pointer_();
00498     }
00499 
00500 // Not to be implemented
00501 private:
00502     interface_cast_addref(class_type const &rhs);
00503     class_type const &operator =(class_type const &rhs);
00504 
00505     // These are defined to placate Borland C/C++
00506     void *operator new(cs_size_t /* si */) { return 0; }
00507     void operator delete(void * /* pv */) {}
00508 };
00509 
00510 
00518 template<   ss_typename_param_k I
00519         >
00520 class interface_cast_test
00521     : protected interface_cast_base<I, noaddref_release<I>, ignore_interface_cast_exception>
00522 {
00523 private:
00524     typedef interface_cast_base<I, noaddref_release<I>, ignore_interface_cast_exception>    parent_class_type;
00525 public:
00527     typedef interface_cast_test<I>                                                          class_type;
00529     typedef ss_typename_type_k parent_class_type::interface_pointer_type                    interface_pointer_type;
00530 #ifdef __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00531 
00532     typedef ss_typename_type_k parent_class_type::interface_type                            interface_type;
00533     typedef protect_refcount<interface_type>                                                *protected_interface_pointer_type;
00534 #else
00535     typedef interface_pointer_type                                                          protected_interface_pointer_type;
00536 #endif // __STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00537 
00538 // Construction
00539 public:
00541 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00542     template <ss_typename_param_k J>
00543     ss_explicit_k interface_cast_test(J &j)
00544         : parent_class_type(j)
00545     {}
00546 #else
00547     ss_explicit_k interface_cast_test(LPUNKNOWN punk)
00548         : parent_class_type(punk)
00549     {}
00550 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00551 
00553     ss_explicit_k interface_cast_test(interface_pointer_type pi)
00554         : parent_class_type(pi)
00555     {}
00556 
00557 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00558     ~interface_cast_test() comstl_throw_0()
00559     {} // We need to provide this to persuade VC6 to call the parent class dtor
00560 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00561 
00563 private:
00564     STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, operator_bool_generator_type, operator_bool_type);
00565 public:
00571     operator operator_bool_type() const
00572     {
00573         return operator_bool_generator_type::translate(NULL != get_pointer_());
00574     }
00579     cs_bool_t operator !() const
00580     {
00581         return NULL == get_pointer_();
00582     }
00584 
00585 // Not to be implemented
00586 private:
00587     interface_cast_test(class_type const &rhs);
00588     class_type const &operator =(class_type const &rhs);
00589 
00590     // These are defined to placate Borland C/C++
00591     void *operator new(cs_size_t /* si */) { return 0; }
00592     void operator delete(void * /* pv */) {}
00593 };
00594 
00595 /* 
00596 
00597 #ifndef _COMSTL_NO_NAMESPACE
00598 # if defined(_STLSOFT_NO_NAMESPACE) || \
00599      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00600 } // namespace comstl
00601 # else
00602 } // namespace comstl_project
00603 # endif /* _STLSOFT_NO_NAMESPACE */
00604 #endif /* !_COMSTL_NO_NAMESPACE */
00605 
00606 /* 
00607  * Shims
00608  */
00609 
00613 template<   ss_typename_param_k I
00614         ,   ss_typename_param_k X
00615         >
00616 inline I get_ptr(comstl_ns_qual(interface_cast_noaddref)<I, X> &p)
00617 {
00618     return p.operator -> ();
00619 }
00620 
00624 template<   ss_typename_param_k I
00625         ,   ss_typename_param_k X
00626         >
00627 inline I const get_ptr(comstl_ns_qual(interface_cast_noaddref)<I, X> const &p)
00628 {
00629     return p.operator -> ();
00630 }
00631 
00635 template<   ss_typename_param_k I
00636         ,   ss_typename_param_k X
00637         >
00638 inline I get_ptr(comstl_ns_qual(interface_cast_addref)<I, X> &p)
00639 {
00640     return p;
00641 }
00642 
00646 template<   ss_typename_param_k I
00647         ,   ss_typename_param_k X
00648         >
00649 inline I const get_ptr(comstl_ns_qual(interface_cast_addref)<I, X> const &p)
00650 {
00651     return p;
00652 }
00653 
00654 /* 
00655 
00657 
00658 /* 
00659 
00660 #if 0
00661 template<   ss_typename_param_k I
00662         >
00663 inline cs_bool_t has_interface()
00664 #endif /* 0 */
00665 
00666 #ifndef _COMSTL_NO_NAMESPACE
00667 # if defined(_STLSOFT_NO_NAMESPACE) || \
00668      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00669 namespace comstl {
00670 # else
00671 namespace comstl_project {
00672 # endif /* _STLSOFT_NO_NAMESPACE */
00673 #endif /* !_COMSTL_NO_NAMESPACE */
00674 
00676 // Unit-testing
00677 
00678 #ifdef STLSOFT_UNITTEST
00679 
00680 namespace unittest
00681 {
00682     ss_bool_t test_comstl_interface_cast(unittest_reporter *r)
00683     {
00684         using stlsoft::unittest::unittest_initialiser;
00685 
00686         ss_bool_t               bSuccess    =   true;
00687 
00688         unittest_initialiser    init(r, "COMSTL", "interface_cast", __FILE__);
00689 
00690         LPSTREAM    pstm;
00691         HRESULT     hr  =   ::CreateStreamOnHGlobal(NULL, true, &pstm);
00692 
00693         if(SUCCEEDED(hr))
00694         {
00695             if(!interface_cast_test<LPSTREAM>(pstm))
00696             {
00697                 r->report("interface_cast_test failed to detect same type ", __LINE__);
00698                 bSuccess = false;
00699             }
00700 
00701             if(get_ptr(interface_cast_noaddref<LPSTREAM>(pstm)) != pstm)
00702             {
00703                 r->report("interface_cast_noaddref did not cast to same type ", __LINE__);
00704                 bSuccess = false;
00705             }
00706 
00707             try
00708             {
00709                 if(get_ptr(interface_cast_noaddref<LPSTORAGE>(pstm)) != NULL)
00710                 {
00711                     r->report("interface_cast_noaddref cast to wrong type ", __LINE__);
00712                     bSuccess = false;
00713                 }
00714             }
00715             catch(bad_interface_cast &x)
00716             {
00717                 STLSOFT_SUPPRESS_UNUSED(x);
00718             }
00719 
00720             LPSTREAM    pstm2   =   interface_cast_addref<LPSTREAM>(pstm);
00721             LPSTORAGE   pstg    =   interface_cast_addref<LPSTORAGE>(pstm);
00722 
00723             if(NULL == pstm2)
00724             {
00725                 r->report("interface_cast_addref did not cast to same type ", __LINE__);
00726                 bSuccess = false;
00727             }
00728             else
00729             {
00730                 pstm2->Release();
00731             }
00732 
00733             if(NULL != pstg)
00734             {
00735                 r->report("interface_cast_addref cast to wrong type ", __LINE__);
00736                 bSuccess = false;
00737                 pstg->Release();
00738             }
00739 
00740             pstm->Release();
00741         }
00742 
00743         return bSuccess;
00744     }
00745 
00746     unittest_registrar    unittest_comstl_interface_cast(test_comstl_interface_cast);
00747 
00748 } // namespace unittest
00749 
00750 #endif /* STLSOFT_UNITTEST */
00751 
00752 /* 
00753 
00754 #ifndef _COMSTL_NO_NAMESPACE
00755 # if defined(_STLSOFT_NO_NAMESPACE) || \
00756      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00757 } // namespace comstl
00758 # else
00759 } // namespace comstl_project
00760 } // namespace stlsoft
00761 # endif /* _STLSOFT_NO_NAMESPACE */
00762 #endif /* !_COMSTL_NO_NAMESPACE */
00763 
00764 /* 
00765 
00766 #endif /* !COMSTL_INCL_H_COMSTL_INTERFACE_CAST */
00767 
00768 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004