1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(BOOST_SPIRIT_KARMA_STRING_GENERATE_FEB_23_2007_1232PM)
7 #define BOOST_SPIRIT_KARMA_STRING_GENERATE_FEB_23_2007_1232PM
8 
9 #if defined(_MSC_VER)
10 #pragma once
11 #endif
12 
13 #include <string>
14 #include <boost/spirit/home/support/char_class.hpp>
15 #include <boost/spirit/home/karma/detail/generate_to.hpp>
16 #include <boost/range/const_iterator.hpp>
17 
18 namespace boost { namespace spirit { namespace karma { namespace detail
19 {
20     ///////////////////////////////////////////////////////////////////////////
21     // pass through character transformation
22     struct pass_through_filter
23     {
24         template <typename Char>
operator ()boost::spirit::karma::detail::pass_through_filter25         Char operator()(Char ch) const
26         {
27             return ch;
28         }
29     };
30 
31     template <typename CharEncoding, typename Tag>
32     struct encoding_filter
33     {
34         template <typename Char>
operator ()boost::spirit::karma::detail::encoding_filter35         Char operator()(Char ch) const
36         {
37             return spirit::char_class::convert<CharEncoding>::to(Tag(), ch);
38         }
39     };
40 
41     ///////////////////////////////////////////////////////////////////////////
42     //  generate a string given by a std::string, applying the given filter
43     template <typename OutputIterator, typename Char, typename Filter>
string_generate(OutputIterator & sink,Char const * str,Filter filter)44     inline bool string_generate(OutputIterator& sink, Char const* str
45       , Filter filter)
46     {
47         for (Char ch = *str; ch != 0; ch = *++str)
48         {
49             *sink = filter(ch);
50             ++sink;
51         }
52         return detail::sink_is_good(sink);
53     }
54 
55     template <typename OutputIterator, typename Container, typename Filter>
string_generate(OutputIterator & sink,Container const & c,Filter filter)56     inline bool string_generate(OutputIterator& sink
57       , Container const& c, Filter filter)
58     {
59         typedef typename traits::container_iterator<Container const>::type
60             iterator;
61 
62         iterator end = boost::end(c);
63         for (iterator it = boost::begin(c); it != end; ++it)
64         {
65             *sink = filter(*it);
66             ++sink;
67         }
68         return detail::sink_is_good(sink);
69     }
70 
71     ///////////////////////////////////////////////////////////////////////////
72     //  generate a string without any transformation
73     template <typename OutputIterator, typename Char>
string_generate(OutputIterator & sink,Char const * str)74     inline bool string_generate(OutputIterator& sink, Char const* str)
75     {
76         return string_generate(sink, str, pass_through_filter());
77     }
78 
79     template <typename OutputIterator, typename Char, typename Traits
80       , typename Allocator>
string_generate(OutputIterator & sink,std::basic_string<Char,Traits,Allocator> const & str)81     inline bool string_generate(OutputIterator& sink
82       , std::basic_string<Char, Traits, Allocator> const& str)
83     {
84         return string_generate(sink, str.c_str(), pass_through_filter());
85     }
86 
87     template <typename OutputIterator, typename Container>
string_generate(OutputIterator & sink,Container const & c)88     inline bool string_generate(OutputIterator& sink
89       , Container const& c)
90     {
91         return string_generate(sink, c, pass_through_filter());
92     }
93 
94     ///////////////////////////////////////////////////////////////////////////
95     //  generate a string given by a pointer, converting according using a
96     //  given character class and case tag
97     template <typename OutputIterator, typename Char, typename CharEncoding
98       , typename Tag>
string_generate(OutputIterator & sink,Char const * str,CharEncoding,Tag)99     inline bool string_generate(OutputIterator& sink
100       , Char const* str
101       , CharEncoding, Tag)
102     {
103         return string_generate(sink, str, encoding_filter<CharEncoding, Tag>());
104     }
105 
106     template <typename OutputIterator, typename Char
107       , typename CharEncoding, typename Tag
108       , typename Traits, typename Allocator>
string_generate(OutputIterator & sink,std::basic_string<Char,Traits,Allocator> const & str,CharEncoding,Tag)109     inline bool string_generate(OutputIterator& sink
110       , std::basic_string<Char, Traits, Allocator> const& str
111       , CharEncoding, Tag)
112     {
113         return string_generate(sink, str.c_str()
114           , encoding_filter<CharEncoding, Tag>());
115     }
116 
117     template <typename OutputIterator, typename Container
118       , typename CharEncoding, typename Tag>
119     inline bool
string_generate(OutputIterator & sink,Container const & c,CharEncoding,Tag)120     string_generate(OutputIterator& sink
121       , Container const& c
122       , CharEncoding, Tag)
123     {
124         return string_generate(sink, c, encoding_filter<CharEncoding, Tag>());
125     }
126 
127     ///////////////////////////////////////////////////////////////////////////
128     template <typename OutputIterator, typename Char>
string_generate(OutputIterator & sink,Char const * str,unused_type,unused_type)129     inline bool string_generate(OutputIterator& sink
130       , Char const* str
131       , unused_type, unused_type)
132     {
133         return string_generate(sink, str, pass_through_filter());
134     }
135 
136     template <typename OutputIterator, typename Char, typename Traits
137       , typename Allocator>
string_generate(OutputIterator & sink,std::basic_string<Char,Traits,Allocator> const & str,unused_type,unused_type)138     inline bool string_generate(OutputIterator& sink
139       , std::basic_string<Char, Traits, Allocator> const& str
140       , unused_type, unused_type)
141     {
142         return string_generate(sink, str.c_str(), pass_through_filter());
143     }
144 
145     template <typename OutputIterator, typename Container>
string_generate(OutputIterator & sink,Container const & c,unused_type,unused_type)146     inline bool string_generate(OutputIterator& sink
147       , Container const& c
148       , unused_type, unused_type)
149     {
150         return string_generate(sink, c, pass_through_filter());
151     }
152 
153 }}}}
154 
155 #endif
156