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  

stlsoft_cstring_maker.h

Go to the documentation of this file.
00001 /* 
00002  * File:        stlsoft_cstring_maker.h
00003  *
00004  * Purpose:     Simple utility class for creating (constant) C-strings.
00005  *
00006  * Created:     14th May 2004
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 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 STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER
00046 #define STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define STLSOFT_VER_H_STLSOFT_CSTRING_MAKER_MAJOR      2
00050 # define STLSOFT_VER_H_STLSOFT_CSTRING_MAKER_MINOR      0
00051 # define STLSOFT_VER_H_STLSOFT_CSTRING_MAKER_REVISION   1
00052 # define STLSOFT_VER_H_STLSOFT_CSTRING_MAKER_EDIT       11
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef STLSOFT_INCL_H_STLSOFT
00060 # include "stlsoft.h"                       // Include the STLSoft root header
00061 #endif /* !STLSOFT_INCL_H_STLSOFT */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_MALLOC_ALLOCATOR
00063 # include "stlsoft_malloc_allocator.h"      //
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_MALLOC_ALLOCATOR */
00065 #ifndef STLSOFT_INCL_H_STLSOFT_CHAR_TRAITS
00066 # include "stlsoft_char_traits.h"           //
00067 #endif /* !STLSOFT_INCL_H_STLSOFT_CHAR_TRAITS */
00068 
00069 /* 
00070  * Namespace
00071  */
00072 
00073 #ifndef _STLSOFT_NO_NAMESPACE
00074 namespace stlsoft
00075 {
00076 #endif /* _STLSOFT_NO_NAMESPACE */
00077 
00078 /* 
00079  * Classes
00080  */
00081 
00083 #if defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION) || \
00084     (   (   !defined(__STLSOFT_COMPILER_IS_GCC) || \
00085         __GNUC__ >= 3) && \
00086         (   !defined(__STLSOFT_COMPILER_IS_MSVC) || \
00087             _MSC_VER != 1100))
00088 template<   ss_typename_param_k C
00089         ,   ss_typename_param_k A = malloc_allocator<C>
00090         ,   ss_typename_param_k T = char_traits<C>
00091         >
00092 struct cstring_maker
00093 {
00094     typedef C                       char_type;
00095     typedef A                       allocator_type;
00096     typedef T                       traits_type;
00097     typedef ss_size_t               size_type;
00098     typedef cstring_maker<C, A, T>  class_type;
00099 
00100 // TODO: Make block private in next release
00101     struct block
00102     {
00103         size_type   n;
00104         char_type   data[1];
00105     };
00106 
00107 public:
00113     static char_type *alloc(size_type cch)
00114     {
00115 #if defined(WIN32) || \
00116     defined(_WIN32)
00117         cch *= 2 / sizeof(char_type);
00118 #endif /* WIN32 || _WIN32 */
00119 
00120         size_type   cb      =   offsetof(block, data) + sizeof(char_type) * (1 + cch);
00121 
00122 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
00123 # ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
00124         ss_typename_type_k allocator_type::template rebind<ss_byte_t>::other    byte_ator;
00125 # else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
00126         ss_typename_type_k allocator_type::rebind<ss_byte_t>::other             byte_ator;
00127 # endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
00128 #else /* ? STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00129         malloc_allocator<ss_byte_t>                                             byte_ator;
00130 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00131 
00132         cb = (cb + 31) & ~31;
00133 
00134         block       *pblock =   static_cast<block*>(static_cast<void*>(byte_ator.allocate(cb, NULL)));
00135 
00136         if(NULL == pblock)
00137         {
00138             return NULL;
00139         }
00140         else
00141         {
00142             pblock->n = cch;
00143             pblock->data[cch] = '\0';
00144 
00145             return &pblock->data[0];
00146         }
00147     }
00153     static char_type *dup(char_type const *s)
00154     {
00155         stlsoft_assert(NULL != s);
00156 
00157         size_type   len =   traits_type::length(s);
00158         char_type   *s_ =   alloc(len);
00159 
00160         if(NULL != s_)
00161         {
00162             traits_type::copy(s_, s, 1 + len);
00163         }
00164 
00165         return s_;
00166     }
00172     static char_type *dup_null(char_type const *s)
00173     {
00174         return (NULL == s) ? NULL : dup(s);
00175     }
00179     static void free(char_type *s)
00180     {
00181 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
00182 # ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
00183         ss_typename_type_k allocator_type::template rebind<ss_byte_t>::other    byte_ator;
00184 # else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
00185         ss_typename_type_k allocator_type::rebind<ss_byte_t>::other             byte_ator;
00186 # endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
00187 #else /* ? STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00188         malloc_allocator<ss_byte_t>                                             byte_ator;
00189 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00190 
00191         if(NULL != s)
00192         {
00193             union
00194             {
00195                 ss_byte_t   *py;
00196                 block       *pblock;
00197             }   u;
00198 
00199             u.py = static_cast<ss_byte_t*>(static_cast<void*>(s)) - offsetof(block, data);
00200 
00201             stlsoft_assert(u.pblock->data[u.pblock->n] == '\0');
00202 
00203             byte_ator.deallocate(u.py, u.pblock->n);
00204         }
00205     }
00206 };
00207 #else /* ? _MSC_VER */
00208 template<   ss_typename_param_k C
00209         >
00210 struct cstring_maker;
00211 
00212 
00213 STLSOFT_TEMPLATE_SPECIALISATION
00214 struct cstring_maker<char>
00215 {
00216 public:
00217     typedef char                        char_type;
00218     typedef malloc_allocator<char_type> allocator_type;
00219     typedef char_traits<char_type>      traits_type;
00220     typedef ss_size_t                   size_type;
00221     typedef cstring_maker<char_type>    class_type;
00222 
00223 public:
00224     static char_type *alloc(size_type cch)
00225     {
00226         return static_cast<char_type*>(malloc((1 + cch) * sizeof(char_type)));
00227     }
00228     static char_type *dup(char_type const *s)
00229     {
00230         return strdup(s);
00231     }
00232     static char_type *dup_null(char_type const *s)
00233     {
00234         return (NULL == s) ? NULL : dup(s);
00235     }
00236     static void free(char_type *s)
00237     {
00238         ::free(s);
00239     }
00240 };
00241 
00242 
00243 # if !defined(__STLSOFT_COMPILER_IS_GCC)
00244 
00245 STLSOFT_TEMPLATE_SPECIALISATION
00246 struct cstring_maker<wchar_t>
00247 {
00248 public:
00249     typedef wchar_t                     char_type;
00250     typedef malloc_allocator<char_type> allocator_type;
00251     typedef char_traits<char_type>      traits_type;
00252     typedef ss_size_t                   size_type;
00253     typedef cstring_maker<char_type>    class_type;
00254 
00255 public:
00256     static char_type *alloc(size_type cch)
00257     {
00258         return static_cast<char_type*>(malloc((1 + cch) * sizeof(char_type)));
00259     }
00260     static char_type *dup(char_type const *s)
00261     {
00262         return _wcsdup(s);
00263     }
00264     static char_type *dup_null(char_type const *s)
00265     {
00266         return (NULL == s) ? NULL : dup(s);
00267     }
00268     static void free(char_type *s)
00269     {
00270         ::free(s);
00271     }
00272 };
00273 # endif /* !__STLSOFT_COMPILER_IS_GCC */
00274 
00275 #endif /* _MSC_VER != 1100 */
00276 
00278 // Unit-testing
00279 
00280 #ifdef STLSOFT_UNITTEST
00281 
00282 namespace unittest
00283 {
00284     ss_bool_t test_stlsoft_cstring_maker(unittest_reporter *r)
00285     {
00286         ss_bool_t               bSuccess    =   true;
00287 
00288         unittest_initialiser    init(r, "STLSoft", "cstring_maker", __FILE__);
00289 
00290         typedef cstring_maker<char>     string_maker_a_t;
00291         typedef cstring_maker<wchar_t>  string_maker_w_t;
00292 
00293         char *s1    =   string_maker_a_t::dup("String #1");
00294 
00295         if(NULL == s1)
00296         {
00297             r->report("dup (ANSI) failed ", __LINE__);
00298             bSuccess = false;
00299         }
00300         else
00301         {
00302 
00303             string_maker_a_t::free(s1);
00304         }
00305 
00306         return bSuccess;
00307     }
00308 
00309     unittest_registrar    unittest_atlstl_string_access(test_stlsoft_cstring_maker);
00310 
00311 } // namespace unittest
00312 
00313 #endif /* STLSOFT_UNITTEST */
00314 
00315 /* 
00316 
00317 #ifndef _STLSOFT_NO_NAMESPACE
00318 } // namespace stlsoft
00319 #endif /* _STLSOFT_NO_NAMESPACE */
00320 
00321 /* 
00322 
00323 #endif /* !STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER */
00324 
00325 /* 

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