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 STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER
00048 #define STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER
00049 
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_MAJOR    4
00052 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_MINOR    0
00053 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_REVISION 2
00054 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_EDIT     45
00055 #endif 
00056 
00057 
00058 
00059 
00060 
00061 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00062 # include <stlsoft/stlsoft.h>
00063 #endif 
00064 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
00065 # include <stlsoft/string/char_traits.hpp>
00066 #endif 
00067 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_BASE
00068 # include <stlsoft/memory/allocator_base.hpp>       
00069 #endif 
00070 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
00071 # include <stlsoft/memory/allocator_selector.hpp>
00072 #endif 
00073 
00074 
00075 
00076 
00077 
00078 #ifndef _STLSOFT_NO_NAMESPACE
00079 namespace stlsoft
00080 {
00081 #endif 
00082 
00083 
00084 
00085 
00086 
00087 #if !defined(_STLSOFT_NO_NAMESPACE) && \
00088     (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
00089         _MSC_VER > 1200)
00090 namespace
00091 {
00092 #endif 
00093 
00094 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00095 
00096 template <ss_typename_param_k C>
00097 struct char_to_byte__traits_
00098 {
00099     static ss_size_t byte_size_(ss_size_t cch)
00100     {
00101         return cch * sizeof(C);
00102     }
00103 };
00104 
00105 STLSOFT_TEMPLATE_SPECIALISATION
00106 struct char_to_byte__traits_<ss_char_a_t>
00107 {
00108     static ss_size_t byte_size_(ss_size_t cch)
00109     {
00110         return cch;
00111     }
00112 };
00113 
00114 #endif 
00115 
00116 #if !defined(_STLSOFT_NO_NAMESPACE) && \
00117     (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
00118         _MSC_VER > 1200)
00119 } 
00120 #endif 
00121 
00128 #if defined(STLSOFT_DOCUMENTATION_SKIP_SECTION) || \
00129     (   (   !defined(STLSOFT_COMPILER_IS_GCC) || \
00130         __GNUC__ >= 3) && \
00131         (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
00132             _MSC_VER != 1100))
00133 template<   ss_typename_param_k C
00134         ,   ss_typename_param_k A = ss_typename_type_def_k allocator_selector<C>::allocator_type
00135         ,   ss_typename_param_k T = stlsoft_char_traits<C>
00136         >
00137 struct cstring_maker
00138 {
00139     typedef C                       char_type;
00140     typedef A                       allocator_type;
00141     typedef T                       traits_type;
00142     typedef ss_size_t               size_type;
00143     typedef cstring_maker<C, A, T>  class_type;
00144 
00145 private:
00146     struct block
00147     {
00148         size_type   n;
00149         char_type   data[1];
00150     };
00151 
00152 public:
00158     static char_type *alloc(size_type cch)
00159     {
00160 #if defined(WIN32) || \
00161     defined(_WIN32)
00162         cch = char_to_byte__traits_<char_type>::byte_size_(cch);
00163 #endif 
00164 
00165         size_type   cb      =   offsetof(block, data) + sizeof(char_type) * (1 + cch);
00166 
00167 #ifdef STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT
00168         ss_typename_type_k allocator_type::ss_template_qual_k rebind<ss_byte_t>::other  byte_ator;
00169 #else 
00170         allocator_selector<ss_byte_t>::allocator_type                                   byte_ator;
00171 #endif 
00172 
00173         cb = (cb + 31) & ~31;
00174 
00175         block       *pblock =   static_cast<block*>(static_cast<void*>(byte_ator.allocate(cb, NULL)));
00176 
00177         if(NULL == pblock)
00178         {
00179             return NULL;
00180         }
00181         else
00182         {
00183             pblock->n = cch;
00184             pblock->data[cch] = '\0';
00185 
00186             return &pblock->data[0];
00187         }
00188     }
00194     static char_type *dup(char_type const* s)
00195     {
00196         STLSOFT_ASSERT(NULL != s);
00197 
00198         size_type   len =   traits_type::length(s);
00199         char_type   *s_ =   alloc(len);
00200 
00201         if(NULL != s_)
00202         {
00203             traits_type::copy(s_, s, 1 + len);
00204         }
00205 
00206         return s_;
00207     }
00213     static char_type *dup_null(char_type const* s)
00214     {
00215         return (NULL == s) ? NULL : dup(s);
00216     }
00220     static void free(char_type *s)
00221     {
00222 #ifdef STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT
00223         ss_typename_type_k allocator_type::ss_template_qual_k rebind<ss_byte_t>::other  byte_ator;
00224 #else 
00225         allocator_selector<ss_byte_t>::allocator_type                                   byte_ator;
00226 #endif 
00227 
00228         if(NULL != s)
00229         {
00230             union
00231             {
00232                 ss_byte_t   *py;
00233                 block       *pblock;
00234             }   u;
00235 
00236             u.py = static_cast<ss_byte_t*>(static_cast<void*>(s)) - offsetof(block, data);
00237 
00238             STLSOFT_ASSERT(u.pblock->data[u.pblock->n] == '\0');
00239 
00240             byte_ator.deallocate(u.py, u.pblock->n);
00241         }
00242     }
00243 };
00244 #else 
00245 template<   ss_typename_param_k C
00246         >
00247 struct cstring_maker;
00248 
00249 
00250 STLSOFT_TEMPLATE_SPECIALISATION
00251 struct cstring_maker<char>
00252 {
00253 public:
00254     typedef char                                            char_type;
00255     typedef allocator_selector<char_type>::allocator_type   allocator_type;
00256     typedef char_traits<char_type>                          traits_type;
00257     typedef ss_size_t                                       size_type;
00258     typedef cstring_maker<char_type>                        class_type;
00259 
00260 public:
00261     static char_type *alloc(size_type cch)
00262     {
00263         return static_cast<char_type*>(malloc((1 + cch) * sizeof(char_type)));
00264     }
00265     static char_type *dup(char_type const* s)
00266     {
00267         return strdup(s);
00268     }
00269     static char_type *dup_null(char_type const* s)
00270     {
00271         return (NULL == s) ? NULL : dup(s);
00272     }
00273     static void free(char_type *s)
00274     {
00275         ::free(s);
00276     }
00277 };
00278 
00279 
00280 # if !defined(STLSOFT_COMPILER_IS_GCC)
00281 
00282 STLSOFT_TEMPLATE_SPECIALISATION
00283 struct cstring_maker<wchar_t>
00284 {
00285 public:
00286     typedef wchar_t                                         char_type;
00287     typedef allocator_selector<char_type>::allocator_type   allocator_type;
00288     typedef char_traits<char_type>                          traits_type;
00289     typedef ss_size_t                                       size_type;
00290     typedef cstring_maker<char_type>                        class_type;
00291 
00292 public:
00293     static char_type *alloc(size_type cch)
00294     {
00295         return static_cast<char_type*>(malloc((1 + cch) * sizeof(char_type)));
00296     }
00297     static char_type *dup(char_type const* s)
00298     {
00299         return _wcsdup(s);
00300     }
00301     static char_type *dup_null(char_type const* s)
00302     {
00303         return (NULL == s) ? NULL : dup(s);
00304     }
00305     static void free(char_type *s)
00306     {
00307         ::free(s);
00308     }
00309 };
00310 # endif 
00311 
00312 #endif 
00313 
00315 
00316 
00317 #ifdef STLSOFT_UNITTEST
00318 # include "./unittest/cstring_maker_unittest_.h"
00319 #endif 
00320 
00321 
00322 
00323 #ifndef _STLSOFT_NO_NAMESPACE
00324 } 
00325 #endif 
00326 
00327 
00328 
00329 #endif 
00330 
00331