include/pantheios/inserters/integer.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////
00002  * File:        pantheios/inserters/integer.hpp
00003  *
00004  * Purpose:     String inserters for fundamental types
00005  *
00006  * Created:     21st June 2005
00007  * Updated:     1st September 2006
00008  *
00009  * Author:      Matthew Wilson
00010  *
00011  * Home:        http://www.pantheios.org/
00012  *
00013  * Copyright:   Matthew Wilson and Synesis Software Pty Ltd, 1999-2005.
00014  *              Matthew Wilson, 2005-2006.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions are met:
00018  *
00019  * - Redistributions of source code must retain the above copyright notice, this
00020  *   list of conditions and the following disclaimer.
00021  * - Redistributions in binary form must reproduce the above copyright notice,
00022  *   this list of conditions and the following disclaimer in the documentation
00023  *   and/or other materials provided with the distribution.
00024  * - Neither the names of Matthew Wilson and Synesis Software nor the names of
00025  *   any contributors may be used to endorse or promote products derived from
00026  *   this software without specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00038  * POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  * ////////////////////////////////////////////////////////////////////// */
00041 
00042 
00049 #ifndef PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_INTEGER
00050 #define PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_INTEGER
00051 
00052 /* /////////////////////////////////////////////////////////////////////////
00053  * Version information
00054  */
00055 
00056 #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
00057 # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_INTEGER_MAJOR    2
00058 # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_INTEGER_MINOR    0
00059 # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_INTEGER_REVISION 9
00060 # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_INTEGER_EDIT     9
00061 #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
00062 
00063 /* /////////////////////////////////////////////////////////////////////////
00064  * Includes
00065  */
00066 
00067 #include <pantheios/pantheios.hpp>
00068 #include <pantheios/inserters/fmt.hpp>
00069 
00070 #include <stlsoft/shims/access/string/fwd.h>
00071 #include <stlsoft/printf_traits.hpp>
00072 
00073 /* /////////////////////////////////////////////////////////////////////////
00074  * Namespace
00075  */
00076 
00077 #if !defined(PANTHEIOS_NO_NAMESPACE)
00078 namespace pantheios
00079 {
00080 
00081 #endif /* !PANTHEIOS_NO_NAMESPACE */
00082 
00083 /* /////////////////////////////////////////////////////////////////////////
00084  * Inserter classes
00085  */
00086 
00119 class integer
00120 {
00123 public:
00124     typedef integer     class_type;
00125 private:
00126     typedef char        char_type;
00128 
00131 private:
00132     template <ss_typename_param_k I>
00133     static size_t sprint_(I const &i, int widthAndFormat, char_type buffer[], size_t cchBuffer)
00134     {
00135         if(0 == widthAndFormat)
00136         {
00137             return static_cast<size_t>(panthieos_inserter_snprintf_(&buffer[0], cchBuffer, ::stlsoft::printf_traits<I>::format_a(), i));
00138         }
00139         else
00140         {
00141             char        szFmt[101];
00142             int         width;
00143             char const  *zeroX;
00144             char const  *leadingMinus   =   "";
00145             char const  *zeroPad;
00146 
00147             if(widthAndFormat < 0)
00148             {
00149                 widthAndFormat  =   -widthAndFormat;
00150                 leadingMinus    =   "-";
00151             }
00152 
00153             zeroX   =   ((fmt::hex | fmt::zeroXPrefix) == (widthAndFormat & (fmt::hex | fmt::zeroXPrefix))) ? "0x" : "";
00154             zeroPad =   (widthAndFormat & fmt::zeroPadded) ? "0" : "";
00155             width   =   widthAndFormat & 0xff;
00156 
00157             panthieos_inserter_snprintf_(  &szFmt[0]
00158                                         ,   STLSOFT_NUM_ELEMENTS(szFmt)
00159                                         ,   "%s%%%s%s%d%s"
00160                                         ,   zeroX
00161                                         ,   leadingMinus
00162                                         ,   zeroPad
00163                                         ,   width
00164                                         ,   (widthAndFormat & fmt::hex) ? "x" : ::stlsoft::printf_traits<I>::format_a() + 1);
00165 
00166             return static_cast<size_t>(panthieos_inserter_snprintf_(buffer, cchBuffer, szFmt, i));
00167         }
00168     }
00169 
00170     template <ss_typename_param_k I>
00171     size_t sprint_(I const &i, int widthAndFormat)
00172     {
00173         return class_type::sprint_(i, widthAndFormat, m_sz, STLSOFT_NUM_ELEMENTS(m_sz));
00174     }
00175 
00176 private:
00177 #ifdef STLSOFT_CF_8BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00178     size_t init_(::stlsoft::sint8_t i);
00179     size_t init_(::stlsoft::uint8_t i);
00180 #endif // STLSOFT_CF_8BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00181 #ifdef STLSOFT_CF_16BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00182     size_t init_(::stlsoft::sint16_t i);
00183     size_t init_(::stlsoft::uint16_t i);
00184 #endif // STLSOFT_CF_16BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00185 #ifdef STLSOFT_CF_32BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00186     size_t init_(::stlsoft::sint32_t i);
00187     size_t init_(::stlsoft::uint32_t i);
00188 #endif // STLSOFT_CF_32BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00189 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00190     size_t init_(::stlsoft::sint64_t i);
00191     size_t init_(::stlsoft::uint64_t i);
00192 #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
00193     size_t init_(int i);
00194     size_t init_(unsigned int i);
00195     size_t init_(long i);
00196     size_t init_(unsigned long i);
00198 
00201 public:
00202 #ifdef STLSOFT_CF_8BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00203 
00204     explicit integer(::stlsoft::sint8_t i, int widthAndFormat = 0);
00206     explicit integer(::stlsoft::uint8_t i, int widthAndFormat = 0);
00207 #endif // STLSOFT_CF_8BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00208 #ifdef STLSOFT_CF_16BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00209 
00210     explicit integer(::stlsoft::sint16_t i, int widthAndFormat = 0);
00212     explicit integer(::stlsoft::uint16_t i, int widthAndFormat = 0);
00213 #endif // STLSOFT_CF_16BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00214 #ifdef STLSOFT_CF_32BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00215 
00216     explicit integer(::stlsoft::sint32_t i, int widthAndFormat = 0);
00218     explicit integer(::stlsoft::uint32_t i, int widthAndFormat = 0);
00219 #endif // STLSOFT_CF_32BIT_INT_EXTENDED_TYPE_IS_DISTINCT
00220 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00221 
00222     explicit integer(::stlsoft::sint64_t i, int widthAndFormat = 0);
00224     explicit integer(::stlsoft::uint64_t i, int widthAndFormat = 0);
00225 #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
00226 
00227     explicit integer(int i, int widthAndFormat = 0);
00229     explicit integer(unsigned int i, int widthAndFormat = 0);
00231     explicit integer(long i, int widthAndFormat = 0);
00233     explicit integer(unsigned long i, int widthAndFormat = 0);
00235 
00238 public:
00240     char const  *data() const;
00242     char const  *c_str() const;
00244     size_t      length() const;
00246 
00249 private:
00250     void construct_() const;
00251     void construct_();
00253 
00256 private:
00257     enum IntegerSize
00258     {
00259             typeIsS32   =   -1
00260         ,   typeIsU32   =   -2
00261 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00262         ,   typeIsS64   =   -3
00263         ,   typeIsU64   =   -4
00264 #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
00265     };
00266 
00267     union u
00268     {
00269         ::stlsoft::sint32_t      s32;   //  typeIsS32
00270         ::stlsoft::uint32_t      u32;   //  typeIsU32
00271 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00272         ::stlsoft::sint64_t      s64;   //  typeIsS64
00273         ::stlsoft::uint64_t      u64;   //  typeIsU64
00274 #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
00275     };
00276 
00277     u           m_value;            // The value, copied for lazy conversion
00278     size_t      m_len;              // Length, and marker for type: 1 == float; 2 == double; 3 == long double
00279     char        m_sz[256];          // Marker for converted, if m_sz[0] == '\0'
00280     const int   m_widthAndFormat;
00282 
00285 private:
00286 #if !defined(STLSOFT_COMPILER_IS_GCC)
00287     integer(class_type const &);
00288 #endif /* compiler */
00289     class_type &operator =(class_type const &);
00291 };
00292 
00293 /* /////////////////////////////////////////////////////////////////////////
00294  * String Access Shims
00295  */
00296 
00297 inline char const *c_str_data_a(integer const &i)
00298 {
00299     return i.data();
00300 }
00301 inline char const *c_str_data(integer const &i)
00302 {
00303     return i.data();
00304 }
00305 
00306 inline size_t c_str_len_a(integer const &i)
00307 {
00308     return i.length();
00309 }
00310 inline size_t c_str_len(integer const &i)
00311 {
00312     return i.length();
00313 }
00314 
00315 inline char const *c_str_ptr_a(integer const &i)
00316 {
00317     return i.c_str();
00318 }
00319 inline char const *c_str_ptr(integer const &i)
00320 {
00321     return i.c_str();
00322 }
00323 
00324 /* /////////////////////////////////////////////////////////////////////////
00325  * Namespace
00326  */
00327 
00328 #if !defined(PANTHEIOS_NO_NAMESPACE)
00329 } /* namespace pantheios */
00330 
00331 namespace stlsoft
00332 {
00333     // 'Export' the string access shims into the STLSoft namespace
00334     //
00335     // c_str_ptr(_a) is not necessary for version 1.0 of Pantheios, but it's
00336     // defined and exported in order to allow for the case where someone
00337     // may find a legitimate use for the conversion classes additional to
00338     // the type-tunnelling of the Panthieos API.
00339 
00340     using ::pantheios::c_str_data_a;
00341     using ::pantheios::c_str_data;
00342 
00343     using ::pantheios::c_str_len;
00344     using ::pantheios::c_str_len_a;
00345 
00346     using ::pantheios::c_str_ptr_a;
00347     using ::pantheios::c_str_ptr;
00348 }
00349 
00350 #endif /* !PANTHEIOS_NO_NAMESPACE */
00351 
00352 /* /////////////////////////////////////////////////////////////////////////
00353  * Inclusion
00354  */
00355 
00356 #ifdef STLSOFT_CF_PRAGMA_ONCE_SUPPORT
00357 # pragma once
00358 #endif /* STLSOFT_CF_PRAGMA_ONCE_SUPPORT */
00359 
00360 /* ////////////////////////////////////////////////////////////////////// */
00361 
00362 #endif /* !PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_INTEGER */
00363 
00364 /* ////////////////////////////////////////////////////////////////////// */

pantheios Library documentation © Matthew Wilson, 2006 SourceForge.net Logo