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  

winstl_shell_allocator.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_shell_allocator.h
00003  *
00004  * Purpose:     shell_allocator class.
00005  *
00006  * Created:     2nd March 2002
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 WINSTL_INCL_H_WINSTL_SHELL_ALLOCATOR
00046 #define WINSTL_INCL_H_WINSTL_SHELL_ALLOCATOR
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define WINSTL_VER_H_WINSTL_SHELL_ALLOCATOR_MAJOR       2
00050 # define WINSTL_VER_H_WINSTL_SHELL_ALLOCATOR_MINOR       0
00051 # define WINSTL_VER_H_WINSTL_SHELL_ALLOCATOR_REVISION    1
00052 # define WINSTL_VER_H_WINSTL_SHELL_ALLOCATOR_EDIT        44
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef WINSTL_INCL_H_WINSTL
00060 # include "winstl.h"                    // Include the WinSTL root header
00061 #endif /* !WINSTL_INCL_H_WINSTL */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_ALLOCATOR_BASE
00063 # include "stlsoft_allocator_base.h"    // Include the STLSoft root header
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_ALLOCATOR_BASE */
00065 #ifndef STLSOFT_INCL_H_STLSOFT_SAP_CAST
00066 # include "stlsoft_sap_cast.h"
00067 #endif /* !STLSOFT_INCL_H_STLSOFT_SAP_CAST */
00068 #include <stdexcept>                    // runtime_error
00069 #include <shlobj.h>                     // SHGetMalloc
00070 
00071 /* 
00072  * Namespace
00073  */
00074 
00075 #ifndef _WINSTL_NO_NAMESPACE
00076 # if defined(_STLSOFT_NO_NAMESPACE) || \
00077      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00078 /* There is no stlsoft namespace, so must define ::winstl */
00079 namespace winstl
00080 {
00081 # else
00082 /* Define stlsoft::winstl_project */
00083 
00084 namespace stlsoft
00085 {
00086 
00087 namespace winstl_project
00088 {
00089 
00090 # endif /* _STLSOFT_NO_NAMESPACE */
00091 #endif /* !_WINSTL_NO_NAMESPACE */
00092 
00093 /* 
00094 
00097 
00101 
00106 
00107 /* 
00108  * Classes
00109  */
00110 
00111 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00112 
00113 template <ss_typename_param_k T>
00114 class shell_allocator;
00115 
00116 // Specialisation for void
00117 STLSOFT_TEMPLATE_SPECIALISATION
00118 class shell_allocator<void>
00119 {
00120 public:
00121     typedef void                            value_type;
00122     typedef shell_allocator<void>           class_type;
00123     typedef void                            *pointer;
00124     typedef void const                      *const_pointer;
00125     typedef ptrdiff_t                       difference_type;
00126     typedef ws_size_t                       size_type;
00127 
00128 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
00129 
00130     template <ss_typename_param_k U>
00131     struct rebind
00132     {
00133         typedef shell_allocator<U>          other;
00134     };
00135 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00136 };
00137 
00138 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00139 
00143 template <ss_typename_param_k T>
00144 class shell_allocator
00145 {
00146 public:
00148     typedef T                               value_type;
00150     typedef shell_allocator<value_type>     class_type;
00152     typedef value_type                      *pointer;
00154     typedef value_type const                *const_pointer;
00156     typedef value_type                      &reference;
00158     typedef value_type const                &const_reference;
00160     typedef ptrdiff_t                       difference_type;
00162     typedef ws_size_t                       size_type;
00164 #ifdef __STLSOFT_CF_ALLOCATOR_TYPED_DEALLOCATE_POINTER
00165     typedef pointer                         deallocate_pointer;
00166 #else
00167     typedef void                            *deallocate_pointer;
00168 #endif /* __STLSOFT_COMPILER_IS_MSVC && _MSC_VER == 1200 */
00169 
00170 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
00171 
00172     template <ss_typename_param_k U>
00173     struct rebind
00174     {
00175         typedef shell_allocator<U>          other;
00176     };
00177 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00178 
00179 // Construction
00180 public:
00182     shell_allocator() winstl_throw_1(stlsoft_ns_qual_std(runtime_error) )
00183         : m_malloc(NULL)
00184     {
00185         _get_malloc();
00186     }
00188 #ifndef __STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
00189     shell_allocator(const shell_allocator &/* rhs */) //winstl_throw_1(stlsoft_ns_qual_std(runtime_error) )
00190     {
00191         _get_malloc();
00192     }
00193 #else
00194     template <ss_typename_param_k U>
00195     shell_allocator(const shell_allocator<U> &/* rhs */) //winstl_throw_1(stlsoft_ns_qual_std(runtime_error) )
00196     {
00197         _get_malloc();
00198     }
00199 #endif /* !__STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
00200 
00201     ~shell_allocator() //winstl_throw_0()
00202     {
00203         if(m_malloc != NULL)
00204         {
00205             m_malloc->Release();
00206         }
00207     }
00208 
00209 // Attributes
00210 public:
00212     size_type max_size() const winstl_throw_0()
00213     {
00214         return static_cast<size_type>(-1) / sizeof(value_type);
00215     }
00216 
00217 // Conversion
00218 public:
00222     pointer address(reference x) const winstl_throw_0()
00223     {
00224         return &x;
00225     }
00229     const_pointer address(const_reference x) const winstl_throw_0()
00230     {
00231         return &x;
00232     }
00233 
00234 // Allocation
00235 public:
00241     pointer allocate(size_type n, shell_allocator<void>::const_pointer pv = NULL)
00242     {
00243         STLSOFT_SUPPRESS_UNUSED(pv);
00244 
00245         shell_allocator<void>::pointer   p   =   static_cast<shell_allocator<void>::pointer>(m_malloc->Alloc(n * sizeof(value_type)));
00246 
00247 #ifdef __STLSOFT_CF_THROW_BAD_ALLOC
00248         if(p == NULL)
00249         {
00250             throw stlsoft_ns_qual_std(bad_alloc)();
00251         }
00252 #endif /* __STLSOFT_CF_THROW_BAD_ALLOC */
00253 
00254         return static_cast<pointer>(p);
00255     }
00256 
00257 #ifdef __STLSOFT_CF_ALLOCATOR_CHARALLOC_METHOD
00258 
00259     char *_Charalloc(size_type n)
00260     {
00261         return sap_cast<char*>(allocate(n, NULL));
00262     }
00263 #endif /* __STLSOFT_CF_ALLOCATOR_CHARALLOC_METHOD */
00264 
00269     void deallocate(pointer p, size_type n)
00270     {
00271         STLSOFT_SUPPRESS_UNUSED(n);
00272 
00273         m_malloc->Free(static_cast<HGLOBAL>(p));
00274     }
00275 
00279     void deallocate(pointer p)
00280     {
00281         m_malloc->Free(static_cast<HGLOBAL>(p));
00282     }
00283 
00284 // Operations
00285 public:
00290     void construct(pointer p, value_type const &x)
00291     {
00292         new(p) value_type(x);
00293     }
00294 
00298     void construct(pointer p)
00299     {
00300         new(p) value_type();
00301     }
00302 
00306     void destroy(pointer p) winstl_throw_0()
00307     {
00308         winstl_destroy_instance(T, value_type, p);
00309     }
00310 
00311 // Implementation
00312 protected:
00313     void _get_malloc() winstl_throw_1(stlsoft_ns_qual_std(runtime_error) )
00314     {
00315         HRESULT hr  =   ::SHGetMalloc(&m_malloc);
00316 
00317 #ifdef __STLSOFT_CF_THROW_BAD_ALLOC
00318         if(FAILED(hr))
00319         {
00320             throw stlsoft_ns_qual_std(runtime_error)("failed to retrieve the shell allocator");
00321         }
00322 #else
00323         STLSOFT_SUPPRESS_UNUSED(hr);
00324 #endif /* __STLSOFT_CF_THROW_BAD_ALLOC */
00325     }
00326 
00327 // Members
00328 protected:
00329     LPMALLOC    m_malloc;
00330 
00331 // Not to be implemented
00332 private:
00333     class_type const &operator =(class_type const &rhs);
00334 };
00335 
00336 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00337 
00338 template <ss_typename_param_k T>
00339 inline ws_bool_t operator ==(const shell_allocator<T> &/* lhs */, const shell_allocator<T> &/* rhs */)
00340 {
00341     return ws_true_v;
00342 }
00343 
00344 template <ss_typename_param_k T>
00345 inline ws_bool_t operator !=(const shell_allocator<T> &/* lhs */, const shell_allocator<T> &/* rhs */)
00346 {
00347     return ws_false_v;
00348 }
00349 
00350 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00351 
00353 // Unit-testing
00354 
00355 #ifdef STLSOFT_UNITTEST
00356 
00357 namespace unittest
00358 {
00359     ss_bool_t test_winstl_shell_allocator(unittest_reporter *r)
00360     {
00361         using stlsoft::unittest::unittest_initialiser;
00362 
00363         ss_bool_t               bSuccess    =   true;
00364 
00365         unittest_initialiser    init(r, "WinSTL", "shell_allocator", __FILE__);
00366 
00367         typedef shell_allocator<int>  int_allocator_t;
00368 
00369         int_allocator_t ator1;
00370 
00371         int     *pi1    =   ator1.allocate(100);
00372 
00373         if(NULL != pi1)
00374         {
00375             ator1.construct(pi1, 1968);
00376 
00377             if(1968 != *pi1)
00378             {
00379                 r->report("construct() failed ", __LINE__);
00380                 bSuccess = false;
00381             }
00382         }
00383 
00384         return bSuccess;
00385     }
00386 
00387     unittest_registrar    unittest_winstl_shell_allocator(test_winstl_shell_allocator);
00388 
00389 } // namespace unittest
00390 
00391 #endif /* STLSOFT_UNITTEST */
00392 
00393 /* 
00394 
00396 
00397 /* 
00398 
00399 #ifndef _WINSTL_NO_NAMESPACE
00400 # if defined(_STLSOFT_NO_NAMESPACE) || \
00401      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00402 } // namespace winstl
00403 # else
00404 } // namespace winstl_project
00405 } // namespace stlsoft
00406 # endif /* _STLSOFT_NO_NAMESPACE */
00407 #endif /* !_WINSTL_NO_NAMESPACE */
00408 
00409 /* 
00410 
00411 #endif /* WINSTL_INCL_H_WINSTL_SHELL_ALLOCATOR */
00412 
00413 /* 

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