- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages
- Examples

# 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 |