Synesis Software STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ...

fastformat/iterators/format_iterator.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////
00002  * File:        fastformat/iterators/format_iterator.hpp
00003  *
00004  * Purpose:     Definition of the fastformat::format_iterator output
00005  *              iterator.
00006  *
00007  * Created:     20th May 2009
00008  * Updated:     16th April 2010
00009  *
00010  * Home:        http://www.fastformat.org/
00011  *
00012  * Copyright (c) 2009-2010, Matthew Wilson and Synesis Software
00013  * All rights reserved.
00014  *
00015  * Redistribution and use in source and binary forms, with or without
00016  * modification, are permitted provided that the following conditions are
00017  * met:
00018  *
00019  * - Redistributions of source code must retain the above copyright notice,
00020  *   this list of conditions and the following disclaimer.
00021  * - Redistributions in binary form must reproduce the above copyright
00022  *   notice, this list of conditions and the following disclaimer in the
00023  *   documentation and/or other materials provided with the distribution.
00024  * - Neither the names of Matthew Wilson and Synesis Software nor the names
00025  *   of any contributors may be used to endorse or promote products derived
00026  *   from this software without specific prior written permission.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00029  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00030  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00031  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00032  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00033  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00034  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00035  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00036  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00037  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00038  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  * ////////////////////////////////////////////////////////////////////// */
00041 
00042 
00048 #ifndef FASTFORMAT_INCL_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR
00049 #define FASTFORMAT_INCL_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR
00050 
00051 /* /////////////////////////////////////////////////////////////////////////
00052  * Version information
00053  */
00054 
00055 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00056 # define FASTFORMAT_VER_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR_MAJOR      1
00057 # define FASTFORMAT_VER_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR_MINOR      1
00058 # define FASTFORMAT_VER_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR_REVISION   5
00059 # define FASTFORMAT_VER_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR_EDIT       7
00060 #endif /* !FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00061 
00062 /* /////////////////////////////////////////////////////////////////////////
00063  * Language
00064  */
00065 
00066 #ifndef __cplusplus
00067 # error This file can only be included in C++ compilation units
00068 #endif /* !__cplusplus */
00069 
00070 /* /////////////////////////////////////////////////////////////////////////
00071  * Includes
00072  */
00073 
00074 #include <fastformat/fastformat.hpp>
00075 #include <fastformat/internal/stlsoft.h>
00076 #include <fastformat/quality/contract.h>
00077 
00078 #include <stlsoft/shims/access/string.hpp>
00079 #include <stlsoft/util/std/iterator_helper.hpp>
00080 
00081 /* /////////////////////////////////////////////////////////////////////////
00082  * Namespace
00083  */
00084 
00085 #if !defined(FASTFORMAT_NO_NAMESPACE)
00086 namespace fastformat
00087 {
00088 namespace iterators
00089 {
00090 #endif /* !FASTFORMAT_NO_NAMESPACE */
00091 
00092 /* /////////////////////////////////////////////////////////////////////////
00093  * Helpers
00094  */
00095 
00096 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00097 
00098 namespace impl
00099 {
00100 
00101     struct no_arg_t
00102     {};
00103 
00104     template <typename T>
00105     struct ref_helper
00106     {
00107     public:
00108         static T const& get_ref(T const& t)
00109         {
00110             return t;
00111         }
00112     };
00113     STLSOFT_TEMPLATE_SPECIALISATION
00114     struct ref_helper<no_arg_t>
00115     {
00116         static ff_char_t const* get_ref(no_arg_t const&)
00117         {
00118             static ff_char_t s_empty[] = { '\0' };
00119 
00120             return s_empty;
00121         }
00122     };
00123 
00124 } /* namespace impl */
00125 
00126 #endif /* !FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00127 
00128 /* /////////////////////////////////////////////////////////////////////////
00129  * Classes
00130  */
00131 
00138 template<   typename S
00139         ,   typename F
00140         ,   typename A1
00141         ,   typename A2
00142         ,   typename A3
00143         ,   typename A4
00144         ,   typename A5
00145         ,   typename A6
00146         ,   typename A7
00147         ,   typename A8
00148         >
00149 class format_output_iterator
00150     : public stlsoft::iterator_base<std::output_iterator_tag, void, void, void, void>
00151 {
00152 public:
00154     typedef format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, A8>    class_type;
00156     typedef S                                                               sink_type;
00158     typedef F                                                               format_type;
00159 private:
00160     typedef std::basic_string<ff_char_t>                                    string_type_;
00161 
00162 private:
00163     class deref_proxy;
00164     friend class deref_proxy;
00165 
00166 #if defined(STLSOFT_COMPILER_IS_MWERKS)
00167 public:
00168 #else
00169 private:
00170 #endif
00171     static impl::no_arg_t const& no_arg_ref_()
00172     {
00173       // NOTE: this is a race-condition, but it's entirely benign
00174 
00175       static impl::no_arg_t r;
00176 
00177       return r;
00178     }
00179 
00180 public:
00182     format_output_iterator(sink_type& sink, format_type const& format)
00183         : m_sink(&sink)
00184         , m_format(::stlsoft::c_str_data(format), ::stlsoft::c_str_len(format))
00185         , m_n(0)
00186         , m_arg1(&no_arg_ref_())
00187         , m_arg2(&no_arg_ref_())
00188         , m_arg3(&no_arg_ref_())
00189         , m_arg4(&no_arg_ref_())
00190         , m_arg5(&no_arg_ref_())
00191         , m_arg6(&no_arg_ref_())
00192         , m_arg7(&no_arg_ref_())
00193         , m_arg8(&no_arg_ref_())
00194     {}
00196     format_output_iterator(
00197         sink_type&          sink
00198     ,   format_type const&  format
00199     ,   unsigned            n
00200     ,   A1 const&           arg1
00201     ,   A2 const&           arg2 = no_arg_ref_()
00202     ,   A3 const&           arg3 = no_arg_ref_()
00203     ,   A4 const&           arg4 = no_arg_ref_()
00204     ,   A5 const&           arg5 = no_arg_ref_()
00205     ,   A6 const&           arg6 = no_arg_ref_()
00206     ,   A7 const&           arg7 = no_arg_ref_()
00207     ,   A8 const&           arg8 = no_arg_ref_()
00208     )
00209         : m_sink(&sink)
00210         , m_format(::stlsoft::c_str_data(format), ::stlsoft::c_str_len(format))
00211         , m_n(n)
00212         , m_arg1(&arg1)
00213         , m_arg2(&arg2)
00214         , m_arg3(&arg3)
00215         , m_arg4(&arg4)
00216         , m_arg5(&arg5)
00217         , m_arg6(&arg6)
00218         , m_arg7(&arg7)
00219         , m_arg8(&arg8)
00220     {}
00221 
00222 private:
00226     class deref_proxy
00227     {
00228     public:
00229         deref_proxy(format_output_iterator* it)
00230             : m_it(it)
00231         {}
00232 
00233     public:
00234         template <typename A>
00235         void operator =(A const& value)
00236         {
00237             m_it->invoke_(value);
00238         }
00239 
00240     private:
00241         format_output_iterator* const m_it;
00242 
00243     private:
00244         void operator =(deref_proxy const&);
00245     };
00246 
00247     template <typename A>
00248     void invoke_(A const& value)
00249     {
00250         switch(m_n)
00251         {
00252             case    0:
00253                 fmt(*m_sink, m_format, value);
00254                 break;
00255             case    1:
00256                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1));
00257                 break;
00258             case    2:
00259                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2));
00260                 break;
00261             case    3:
00262                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3));
00263                 break;
00264             case    4:
00265                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3), impl::ref_helper<A4>::get_ref(*m_arg4));
00266                 break;
00267             case    5:
00268                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3), impl::ref_helper<A4>::get_ref(*m_arg4), impl::ref_helper<A5>::get_ref(*m_arg5));
00269                 break;
00270             case    6:
00271                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3), impl::ref_helper<A4>::get_ref(*m_arg4), impl::ref_helper<A5>::get_ref(*m_arg5), impl::ref_helper<A6>::get_ref(*m_arg6));
00272                 break;
00273             case    7:
00274                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3), impl::ref_helper<A4>::get_ref(*m_arg4), impl::ref_helper<A5>::get_ref(*m_arg5), impl::ref_helper<A6>::get_ref(*m_arg6), impl::ref_helper<A7>::get_ref(*m_arg7));
00275                 break;
00276             case    8:
00277                 fmt(*m_sink, m_format, value, impl::ref_helper<A1>::get_ref(*m_arg1), impl::ref_helper<A2>::get_ref(*m_arg2), impl::ref_helper<A3>::get_ref(*m_arg3), impl::ref_helper<A4>::get_ref(*m_arg4), impl::ref_helper<A5>::get_ref(*m_arg5), impl::ref_helper<A6>::get_ref(*m_arg6), impl::ref_helper<A7>::get_ref(*m_arg7), impl::ref_helper<A8>::get_ref(*m_arg8));
00278                 break;
00279         }
00280     }
00281 
00282 public:
00284     deref_proxy operator *()
00285     {
00286         return deref_proxy(this);
00287     }
00289     class_type& operator ++()
00290     {
00291         return *this;
00292     }
00294     class_type operator ++(int)
00295     {
00296         return *this;
00297     }
00298 
00299 private:
00300     sink_type*      m_sink;
00301     string_type_    m_format;
00302     unsigned        m_n;
00303     A1 const*       m_arg1;
00304     A2 const*       m_arg2;
00305     A3 const*       m_arg3;
00306     A4 const*       m_arg4;
00307     A5 const*       m_arg5;
00308     A6 const*       m_arg6;
00309     A7 const*       m_arg7;
00310     A8 const*       m_arg8;
00311 };
00312 
00313 #ifdef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00314 
00356 template<   typename S
00357         ,   typename F
00358         ,   typename A1
00359         ,   typename A2
00360         ,   typename A3
00361         ,   typename A4
00362         ,   typename A5
00363         ,   typename A6
00364         ,   typename A7
00365         ,   typename A8
00366         >
00367 format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, A8> format_iterator(S& sink, F const& format, ...)
00368 {}
00369 #else /* ? FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00370 template<   typename S
00371         ,   typename F
00372         >
00373 inline format_output_iterator<S, F, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(S& sink, F const& format)
00374 {
00375     return format_output_iterator<S, F, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format);
00376 }
00377 template<   typename S
00378         ,   typename F
00379         ,   typename A1
00380         >
00381 inline format_output_iterator<S, F, A1, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(
00382     S&          sink
00383 ,   F const&    format
00384 ,   A1 const&   arg1
00385 )
00386 {
00387     return format_output_iterator<S, F, A1, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format, 1u, arg1);
00388 }
00389 template<   typename S
00390         ,   typename F
00391         ,   typename A1
00392         ,   typename A2
00393         >
00394 inline format_output_iterator<S, F, A1, A2, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(
00395     S&          sink
00396 ,   F const&    format
00397 ,   A1 const&   arg1
00398 ,   A2 const&   arg2
00399 )
00400 {
00401     return format_output_iterator<S, F, A1, A2, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format, 2u, arg1, arg2);
00402 }
00403 
00404 template<   typename S
00405         ,   typename F
00406         ,   typename A1
00407         ,   typename A2
00408         ,   typename A3
00409         >
00410 inline format_output_iterator<S, F, A1, A2, A3, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(
00411     S&          sink
00412 ,   F const&    format
00413 ,   A1 const&   arg1
00414 ,   A2 const&   arg2
00415 ,   A3 const&   arg3
00416 )
00417 {
00418     return format_output_iterator<S, F, A1, A2, A3, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format, 3u, arg1, arg2, arg3);
00419 }
00420 template<   typename S
00421         ,   typename F
00422         ,   typename A1
00423         ,   typename A2
00424         ,   typename A3
00425         ,   typename A4
00426         >
00427 inline format_output_iterator<S, F, A1, A2, A3, A4, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(
00428     S&          sink
00429 ,   F const&    format
00430 ,   A1 const&   arg1
00431 ,   A2 const&   arg2
00432 ,   A3 const&   arg3
00433 ,   A4 const&   arg4
00434 )
00435 {
00436     return format_output_iterator<S, F, A1, A2, A3, A4, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format, 4u, arg1, arg2, arg3, arg4);
00437 }
00438 template<   typename S
00439         ,   typename F
00440         ,   typename A1
00441         ,   typename A2
00442         ,   typename A3
00443         ,   typename A4
00444         ,   typename A5
00445         >
00446 inline format_output_iterator<S, F, A1, A2, A3, A4, A5, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t> format_iterator(
00447     S&          sink
00448 ,   F const&    format
00449 ,   A1 const&   arg1
00450 ,   A2 const&   arg2
00451 ,   A3 const&   arg3
00452 ,   A4 const&   arg4
00453 ,   A5 const&   arg5
00454 )
00455 {
00456     return format_output_iterator<S, F, A1, A2, A3, A4, A5, impl::no_arg_t, impl::no_arg_t, impl::no_arg_t>(sink, format, 5u, arg1, arg2, arg3, arg4, arg5);
00457 }
00458 template<   typename S
00459         ,   typename F
00460         ,   typename A1
00461         ,   typename A2
00462         ,   typename A3
00463         ,   typename A4
00464         ,   typename A5
00465         ,   typename A6
00466         >
00467 inline format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, impl::no_arg_t, impl::no_arg_t> format_iterator(
00468     S&          sink
00469 ,   F const&    format
00470 ,   A1 const&   arg1
00471 ,   A2 const&   arg2
00472 ,   A3 const&   arg3
00473 ,   A4 const&   arg4
00474 ,   A5 const&   arg5
00475 ,   A6 const&   arg6
00476 )
00477 {
00478     return format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, impl::no_arg_t, impl::no_arg_t>(sink, format, 6u, arg1, arg2, arg3, arg4, arg5, arg6);
00479 }
00480 template<   typename S
00481         ,   typename F
00482         ,   typename A1
00483         ,   typename A2
00484         ,   typename A3
00485         ,   typename A4
00486         ,   typename A5
00487         ,   typename A6
00488         ,   typename A7
00489         >
00490 inline format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, impl::no_arg_t> format_iterator(
00491     S&          sink
00492 ,   F const&    format
00493 ,   A1 const&   arg1
00494 ,   A2 const&   arg2
00495 ,   A3 const&   arg3
00496 ,   A4 const&   arg4
00497 ,   A5 const&   arg5
00498 ,   A6 const&   arg6
00499 ,   A7 const&   arg7
00500 )
00501 {
00502     return format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, impl::no_arg_t>(sink, format, 7u, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
00503 }
00504 template<   typename S
00505         ,   typename F
00506         ,   typename A1
00507         ,   typename A2
00508         ,   typename A3
00509         ,   typename A4
00510         ,   typename A5
00511         ,   typename A6
00512         ,   typename A7
00513         ,   typename A8
00514         >
00515 inline format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, A8> format_iterator(
00516     S&          sink
00517 ,   F const&    format
00518 ,   A1 const&   arg1
00519 ,   A2 const&   arg2
00520 ,   A3 const&   arg3
00521 ,   A4 const&   arg4
00522 ,   A5 const&   arg5
00523 ,   A6 const&   arg6
00524 ,   A7 const&   arg7
00525 ,   A8 const&   arg8
00526 )
00527 {
00528     return format_output_iterator<S, F, A1, A2, A3, A4, A5, A6, A7, A8>(sink, format, 8u, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
00529 }
00530 #endif /* FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00531 
00532 /* /////////////////////////////////////////////////////////////////////////
00533  * Namespace
00534  */
00535 
00536 #if !defined(FASTFORMAT_NO_NAMESPACE)
00537 } /* namespace iterators */
00538 using ::fastformat::iterators::format_iterator;
00539 } /* namespace fastformat */
00540 #endif /* !FASTFORMAT_NO_NAMESPACE */
00541 
00542 /* /////////////////////////////////////////////////////////////////////////
00543  * Inclusion
00544  */
00545 
00546 #ifdef STLSOFT_PPF_pragma_once_SUPPORT
00547 # pragma once
00548 #endif /* STLSOFT_PPF_pragma_once_SUPPORT */
00549 
00550 /* ////////////////////////////////////////////////////////////////////// */
00551 
00552 #endif /* FASTFORMAT_INCL_FASTFORMAT_ITERATORS_HPP_FORMAT_ITERATOR */
00553 
00554 /* ///////////////////////////// end of file //////////////////////////// */

FastFormat Library documentation © Matthew Wilson, 2006-2009 SourceForge.net Logo