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 
00048 #ifndef WINSTL_INCL_WINSTL_CONVERSION_HPP_INT_TO_STRING
00049 #define WINSTL_INCL_WINSTL_CONVERSION_HPP_INT_TO_STRING
00050 
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_MAJOR      2
00053 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_MINOR      1
00054 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_REVISION   4
00055 # define _WINSTL_VER_WINSTL_CONVERSION_HPP_INT_TO_STRING_EDIT       41
00056 #endif 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00073 # include <winstl/winstl.h>
00074 #endif 
00075 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INT_TO_STRING
00076 # include <stlsoft/conversion/integer_to_string.hpp>
00077 #endif 
00078 #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_THREAD_MUTEX
00079 # include <winstl/synch/thread_mutex.hpp>
00080 #endif 
00081 #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_SPIN_MUTEX
00082 # include <winstl/synch/spin_mutex.hpp>
00083 #endif 
00084 #ifndef STLSOFT_INCL_STLSOFT_SYNCH_HPP_LOCK_SCOPE
00085 # include <stlsoft/synch/lock_scope.hpp>
00086 #endif 
00087 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
00088 # include <stlsoft/conversion/sap_cast.hpp>
00089 #endif 
00090 
00091 
00092 
00093 
00094 
00095 #ifndef _WINSTL_NO_NAMESPACE
00096 # if defined(_STLSOFT_NO_NAMESPACE) || \
00097      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00098 
00099 namespace winstl
00100 {
00101 # else
00102 
00103 
00104 namespace stlsoft
00105 {
00106 
00107 namespace winstl_project
00108 {
00109 
00110 # endif 
00111 #endif 
00112 
00113 
00114 
00115 
00116 
00117 #if defined(_WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES)
00118 # if defined(_DLL) || \
00119      defined(__DLL__) || \
00120      defined(_WINDLL) || \
00121      defined(_USRDLL) || \
00122      defined(_AFXDLL)
00123 #  pragma message("Using _WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES when building DLLs will result in their not being loadable dynamically (via LoadLibrary())")
00124 # endif 
00125 #endif 
00126 
00127 
00128 
00129 
00130 
00131 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00132 
00133 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00134 namespace int_to_string_tls
00135 {
00136 #endif 
00137 
00138 
00139 
00140 
00141 struct thread_mx_
00142     : public thread_mutex
00143 {
00144 public:
00145     thread_mx_()
00146     {}
00147 
00148     void* operator new(ws_size_t , void* p)
00149     {
00150         return p;
00151     }
00152 
00153 #if !defined(STLSOFT_COMPILER_IS_BORLAND) && \
00154     (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
00155         _MSC_VER >= 1200)
00156     void operator delete(void* , void* )
00157     {}
00158 #endif 
00159     void operator delete(void*)
00160     {}
00161 };
00162 
00163 
00164 template< ss_typename_param_k C
00165         , ws_size_t           CCH
00166         >
00167 struct Slot
00168 {
00169     Slot(Slot* next)
00170         : next(next)
00171     {}
00172     ~Slot() stlsoft_throw_0()
00173     {
00174         delete next;
00175     }
00176 
00177     
00178     
00179     
00180     
00181     
00182     
00183     
00184     
00185     
00186     
00187     
00188     
00189     
00190     void* operator new(ws_size_t cb)
00191     {
00192         return ::HeapAlloc(::GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, cb);
00193     }
00194     void operator delete(void* pv)
00195     {
00196         ::HeapFree(::GetProcessHeap(), 0, pv);
00197     }
00198 
00199     C       buff[CCH];
00200     Slot*   next;
00201 };
00202 
00203 template< ss_typename_param_k C
00204         , ws_size_t           CCH
00205         >
00206 struct Key
00207 {
00208     typedef Slot<C, CCH>    Slot;
00209 
00210     
00211     
00212     
00213     
00214     
00215     
00216     
00217     
00218     
00219 
00220     Key()
00221     {
00222         
00223         
00224         
00225         
00226         
00227         
00228         
00229         
00230         
00231         
00232 
00233         
00234         spin_mutex                                                      smx(&m_ctor);
00235         stlsoft_ns_qual(lock_scope)<spin_mutex, spin_mutex_lock_traits> lock(smx);
00236 
00237         if(0 == m_init++) 
00238         {
00239             
00240 
00241             
00242             
00243             
00244             
00245             
00246             
00247 
00248             
00249             
00250 
00251             new (&mx()) thread_mx_();
00252 
00253             m_index =   ::TlsAlloc();
00254 
00255             
00256             
00257             
00258             
00259             
00260             
00261             
00262             
00263             if(TLS_OUT_OF_INDEXES == m_index)
00264             {
00265                 ::RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, 0);
00266             }
00267         }
00268     }
00269 
00270     ~Key() stlsoft_throw_0()
00271     {
00272         if(0 == ::InterlockedDecrement((LPLONG)&m_init))
00273         {
00274             
00275             
00276             delete m_top;
00277 
00278             
00279             ::TlsFree(m_index);
00280 
00281             
00282             mx().~thread_mutex();
00283         }
00284     }
00285 
00286     Slot* GetSlot()
00287     {
00288         
00289         return sap_cast<Slot*>(::TlsGetValue(m_index));
00290     }
00291 
00292     Slot* AllocSlot()
00293     {
00294         Slot* next;
00295 
00296         { 
00297             stlsoft_ns_qual(lock_scope)<thread_mutex, thread_mutex_lock_traits>  lock(mx());
00298 
00299             m_top = next = new Slot(m_top);
00300         }
00301 
00302         ::TlsSetValue(m_index, next);
00303 
00304         return next;
00305     }
00306 
00307 
00308 private:
00309     thread_mutex &mx()
00310     {
00311         return *static_cast<thread_mutex*>(static_cast<void*>(&m__mx.bytes[0]));
00312     }
00313 
00314 private:
00315 #if 0
00316 
00317     ws_dword_t      m_index;
00318     Slot*           m_top;
00319     thread_mutex    m_mx;
00320 #else 
00321 
00322     ws_dword_t      m_index;
00323     Slot*           m_top;
00324     union
00325     {
00326         ws_byte_t   bytes[sizeof(thread_mutex)];
00327         long double ld;
00328     }               m__mx;
00329     ws_sint32_t     m_init; 
00330     ws_sint32_t     m_ctor; 
00331 #endif 
00332 };
00333 
00334 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00335 } 
00336 #endif 
00337 
00338 
00339 template< ss_typename_param_k C
00340         , ws_size_t           CCH
00341         >
00342 inline C* i2str_get_tss_buffer()
00343 {
00344 #if defined(_WINSTL_INT_TO_STRING_USE_DECLSPECTHREAD_FOR_EXES)
00345     __declspec(thread) static C s_buffer[CCH];
00346 
00347     return s_buffer;
00348 #else
00349 
00350 #ifdef STLSOFT_CF_NAMESPACE_SUPPORT
00351     typedef int_to_string_tls::Key<C, CCH>      Key;
00352     typedef int_to_string_tls::Slot<C, CCH>     Slot;
00353 #else
00354     typedef Key<C, CCH>                         Key;
00355     typedef Slot<C, CCH>                        Slot;
00356 #endif 
00357 
00358     static Key  s_index;
00359     Slot*       slot = s_index.GetSlot();
00360 
00361     if(NULL == slot)
00362     {
00363         slot = s_index.AllocSlot();
00364     }
00365 
00366     return slot->buff;
00367 #endif 
00368 }
00369 
00370 #endif 
00371 
00388 template<ss_typename_param_k C>
00389 inline C const* int_to_string(ws_sint8_t value)
00390 {
00391     const ws_size_t CCH     = 21; 
00392     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00393 
00394     return stlsoft::integer_to_string(buffer, CCH, value);
00395 }
00396 
00413 template<ss_typename_param_k C>
00414 inline C const* int_to_string(ws_uint8_t value)
00415 {
00416     const ws_size_t CCH     = 21; 
00417     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00418 
00419     return stlsoft::integer_to_string(buffer, CCH, value);
00420 }
00421 
00438 template<ss_typename_param_k C>
00439 inline C const* int_to_string(ws_sint16_t value)
00440 {
00441     const ws_size_t CCH     = 21; 
00442     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00443 
00444     return stlsoft::integer_to_string(buffer, CCH, value);
00445 }
00446 
00463 template<ss_typename_param_k C>
00464 inline C const* int_to_string(ws_uint16_t value)
00465 {
00466     const ws_size_t CCH     = 21; 
00467     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00468 
00469     return stlsoft::integer_to_string(buffer, CCH, value);
00470 }
00471 
00488 template<ss_typename_param_k C>
00489 inline C const* int_to_string(ws_sint32_t value)
00490 {
00491     const ws_size_t CCH     = 21; 
00492     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00493 
00494     return stlsoft::integer_to_string(buffer, CCH, value);
00495 }
00496 
00513 template<ss_typename_param_k C>
00514 inline C const* int_to_string(ws_uint32_t value)
00515 {
00516     const ws_size_t CCH     = 21; 
00517     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00518 
00519     return stlsoft::integer_to_string(buffer, CCH, value);
00520 }
00521 
00538 template<ss_typename_param_k C>
00539 inline C const* int_to_string(ws_sint64_t const& value)
00540 {
00541     const ws_size_t CCH     = 21; 
00542     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00543 
00544     return stlsoft::integer_to_string(buffer, CCH, value);
00545 }
00546 
00563 template<ss_typename_param_k C>
00564 inline C const* int_to_string(ws_uint64_t const& value)
00565 {
00566     const ws_size_t CCH     = 21; 
00567     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00568 
00569     return stlsoft::integer_to_string(buffer, CCH, value);
00570 }
00571 
00572 
00573 #ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
00574 
00575 template<ss_typename_param_k C>
00576 inline C const* int_to_string(int const& value)
00577 {
00578     const ws_size_t CCH     = 21; 
00579     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00580 
00581     return stlsoft::integer_to_string(buffer, CCH, value);
00582 }
00583 
00584 template<ss_typename_param_k C>
00585 inline C const* int_to_string(unsigned int const& value)
00586 {
00587     const ws_size_t CCH     = 21; 
00588     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00589 
00590     return stlsoft::integer_to_string(buffer, CCH, value);
00591 }
00592 
00593 #endif 
00594 
00595 #ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
00596 
00597 template<ss_typename_param_k C>
00598 inline C const* int_to_string(long const& value)
00599 {
00600     const ws_size_t CCH     = 21; 
00601     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00602 
00603     return stlsoft::integer_to_string(buffer, CCH, value);
00604 }
00605 
00606 template<ss_typename_param_k C>
00607 inline C const* int_to_string(unsigned long const& value)
00608 {
00609     const ws_size_t CCH     = 21; 
00610     C*              buffer  = i2str_get_tss_buffer<C, CCH>();
00611 
00612     return stlsoft::integer_to_string(buffer, CCH, value);
00613 }
00614 
00615 #endif 
00616 
00618 
00619 
00620 #ifdef STLSOFT_UNITTEST
00621 # include "./unittest/int_to_string_unittest_.h"
00622 #endif 
00623 
00624 
00625 
00626 #ifndef _WINSTL_NO_NAMESPACE
00627 # if defined(_STLSOFT_NO_NAMESPACE) || \
00628      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00629 } 
00630 # else
00631 } 
00632 } 
00633 # endif 
00634 #endif 
00635 
00636 
00637 
00638 #endif 
00639 
00640