3 // Copyright Neil Groves 2014.
4 // Use, modification and distribution is subject to the Boost Software
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see http://www.boost.org/libs/range/
10 #ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
11 #define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
13 #include <boost/config.hpp>
14 #include <boost/range/concepts.hpp>
15 #include <boost/range/begin.hpp>
16 #include <boost/range/end.hpp>
17 #include <boost/range/iterator.hpp>
18 #include <boost/range/iterator_range_core.hpp>
19 #include <boost/mpl/if.hpp>
20 #include <boost/type_traits/is_array.hpp>
21 #include <boost/type_traits/remove_extent.hpp>
26 namespace range_detail
29 template<typename Sep, typename Prefix, typename Postfix>
30 struct formatted_holder
32 typedef typename boost::mpl::if_<
34 const typename boost::remove_extent<Sep>::type*,
38 typedef typename boost::mpl::if_<
39 boost::is_array<Prefix>,
40 const typename boost::remove_extent<Prefix>::type*,
44 typedef typename boost::mpl::if_<
45 boost::is_array<Postfix>,
46 const typename boost::remove_extent<Postfix>::type*,
51 const separator_t& sep,
52 const prefix_t& prefix,
53 const postfix_t& postfix)
65 template<typename Iter, typename Sep, typename Prefix, typename Postfix>
67 : public boost::iterator_range<Iter>
69 typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
71 formatted_range(Iter first, Iter last, const holder_t& holder)
72 : boost::iterator_range<Iter>(first, last)
77 template<typename OStream>
78 void write(OStream& out) const
80 Iter it(this->begin());
81 out << m_holder.m_prefix;
82 if (it != this->end())
85 for (++it; it != this->end(); ++it)
87 out << m_holder.m_sep << *it;
90 out << m_holder.m_postfix;
98 typename SinglePassRange,
103 inline range_detail::formatted_range<
104 typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
107 const SinglePassRange& rng,
108 const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
111 typedef typename range_iterator<const SinglePassRange>::type iterator;
112 return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
113 boost::begin(rng), boost::end(rng), holder);
116 template<typename Char, typename Traits, typename Iter, typename Sep,
117 typename Prefix, typename Postfix>
118 std::basic_ostream<Char, Traits>&
120 std::basic_ostream<Char, Traits>& out,
121 const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
127 } // namespace range_detail
132 template<typename Sep, typename Prefix, typename Postfix>
133 range_detail::formatted_holder<Sep, Prefix, Postfix>
134 formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
136 return range_detail::formatted_holder<Sep,Prefix,Postfix>(
137 sep, prefix, postfix);
140 template<typename Sep, typename Prefix>
141 range_detail::formatted_holder<Sep, Prefix, char>
142 formatted(const Sep& sep, const Prefix& prefix)
144 return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
147 template<typename Sep>
148 range_detail::formatted_holder<Sep, char, char>
149 formatted(const Sep& sep)
151 return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
154 inline range_detail::formatted_holder<char, char, char>
157 return range_detail::formatted_holder<char, char, char>(',', '{', '}');
160 using range_detail::formatted_range;
162 template<typename SinglePassRange, typename Sep, typename Prefix,
164 inline boost::range_detail::formatted_range<
165 typename boost::range_iterator<const SinglePassRange>::type,
169 const SinglePassRange& rng,
171 const Prefix& prefix,
172 const Postfix& postfix
175 typedef typename boost::range_iterator<const SinglePassRange>::type
178 typedef boost::range_detail::formatted_range<
179 iterator_t, Sep, Prefix, Postfix> result_t;
181 typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
184 return result_t(boost::begin(rng), boost::end(rng),
185 holder_t(sep, prefix, postfix));
188 template<typename SinglePassRange, typename Sep, typename Prefix>
189 inline boost::range_detail::formatted_range<
190 typename boost::range_iterator<const SinglePassRange>::type,
194 const SinglePassRange& rng,
196 const Prefix& prefix)
198 return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
201 template<typename SinglePassRange, typename Sep>
202 inline boost::range_detail::formatted_range<
203 typename boost::range_iterator<const SinglePassRange>::type,
206 format(const SinglePassRange& rng, const Sep& sep)
208 return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
211 template<typename SinglePassRange>
212 inline boost::range_detail::formatted_range<
213 typename boost::range_iterator<const SinglePassRange>::type,
216 format(const SinglePassRange& rng)
218 return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
221 } // namespace adaptors
225 using boost::range_detail::formatted_range;
229 #endif // include guard