File indexing completed on 2025-01-18 09:51:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
0011 #define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
0012
0013 #include <boost/config.hpp>
0014 #include <boost/range/concepts.hpp>
0015 #include <boost/range/begin.hpp>
0016 #include <boost/range/end.hpp>
0017 #include <boost/range/iterator.hpp>
0018 #include <boost/range/iterator_range_core.hpp>
0019 #include <boost/mpl/if.hpp>
0020 #include <boost/type_traits/is_array.hpp>
0021 #include <boost/type_traits/remove_extent.hpp>
0022 #include <ostream>
0023
0024 namespace boost
0025 {
0026 namespace range_detail
0027 {
0028
0029 template<typename Sep, typename Prefix, typename Postfix>
0030 struct formatted_holder
0031 {
0032 typedef typename boost::mpl::if_<
0033 boost::is_array<Sep>,
0034 const typename boost::remove_extent<Sep>::type*,
0035 Sep
0036 >::type separator_t;
0037
0038 typedef typename boost::mpl::if_<
0039 boost::is_array<Prefix>,
0040 const typename boost::remove_extent<Prefix>::type*,
0041 Prefix
0042 >::type prefix_t;
0043
0044 typedef typename boost::mpl::if_<
0045 boost::is_array<Postfix>,
0046 const typename boost::remove_extent<Postfix>::type*,
0047 Postfix
0048 >::type postfix_t;
0049
0050 formatted_holder(
0051 const separator_t& sep,
0052 const prefix_t& prefix,
0053 const postfix_t& postfix)
0054 : m_sep(sep)
0055 , m_prefix(prefix)
0056 , m_postfix(postfix)
0057 {
0058 }
0059
0060 separator_t m_sep;
0061 prefix_t m_prefix;
0062 postfix_t m_postfix;
0063 };
0064
0065 template<typename Iter, typename Sep, typename Prefix, typename Postfix>
0066 class formatted_range
0067 : public boost::iterator_range<Iter>
0068 {
0069 typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
0070 public:
0071 formatted_range(Iter first, Iter last, const holder_t& holder)
0072 : boost::iterator_range<Iter>(first, last)
0073 , m_holder(holder)
0074 {
0075 }
0076
0077 template<typename OStream>
0078 void write(OStream& out) const
0079 {
0080 Iter it(this->begin());
0081 out << m_holder.m_prefix;
0082 if (it != this->end())
0083 {
0084 out << *it;
0085 for (++it; it != this->end(); ++it)
0086 {
0087 out << m_holder.m_sep << *it;
0088 }
0089 }
0090 out << m_holder.m_postfix;
0091 }
0092
0093 private:
0094 holder_t m_holder;
0095 };
0096
0097 template<
0098 typename SinglePassRange,
0099 typename Sep,
0100 typename Prefix,
0101 typename Postfix
0102 >
0103 inline range_detail::formatted_range<
0104 typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
0105 >
0106 operator|(
0107 const SinglePassRange& rng,
0108 const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
0109 )
0110 {
0111 typedef typename range_iterator<const SinglePassRange>::type iterator;
0112 return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
0113 boost::begin(rng), boost::end(rng), holder);
0114 }
0115
0116 template<typename Char, typename Traits, typename Iter, typename Sep,
0117 typename Prefix, typename Postfix>
0118 std::basic_ostream<Char, Traits>&
0119 operator<<(
0120 std::basic_ostream<Char, Traits>& out,
0121 const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
0122 {
0123 writer.write(out);
0124 return out;
0125 }
0126
0127 }
0128
0129 namespace adaptors
0130 {
0131
0132 template<typename Sep, typename Prefix, typename Postfix>
0133 range_detail::formatted_holder<Sep, Prefix, Postfix>
0134 formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
0135 {
0136 return range_detail::formatted_holder<Sep,Prefix,Postfix>(
0137 sep, prefix, postfix);
0138 }
0139
0140 template<typename Sep, typename Prefix>
0141 range_detail::formatted_holder<Sep, Prefix, char>
0142 formatted(const Sep& sep, const Prefix& prefix)
0143 {
0144 return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
0145 }
0146
0147 template<typename Sep>
0148 range_detail::formatted_holder<Sep, char, char>
0149 formatted(const Sep& sep)
0150 {
0151 return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
0152 }
0153
0154 inline range_detail::formatted_holder<char, char, char>
0155 formatted()
0156 {
0157 return range_detail::formatted_holder<char, char, char>(',', '{', '}');
0158 }
0159
0160 using range_detail::formatted_range;
0161
0162 template<typename SinglePassRange, typename Sep, typename Prefix,
0163 typename Postfix>
0164 inline boost::range_detail::formatted_range<
0165 typename boost::range_iterator<const SinglePassRange>::type,
0166 Sep, Prefix, Postfix
0167 >
0168 format(
0169 const SinglePassRange& rng,
0170 const Sep& sep,
0171 const Prefix& prefix,
0172 const Postfix& postfix
0173 )
0174 {
0175 typedef typename boost::range_iterator<const SinglePassRange>::type
0176 iterator_t;
0177
0178 typedef boost::range_detail::formatted_range<
0179 iterator_t, Sep, Prefix, Postfix> result_t;
0180
0181 typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
0182 holder_t;
0183
0184 return result_t(boost::begin(rng), boost::end(rng),
0185 holder_t(sep, prefix, postfix));
0186 }
0187
0188 template<typename SinglePassRange, typename Sep, typename Prefix>
0189 inline boost::range_detail::formatted_range<
0190 typename boost::range_iterator<const SinglePassRange>::type,
0191 Sep, Prefix, char
0192 >
0193 format(
0194 const SinglePassRange& rng,
0195 const Sep& sep,
0196 const Prefix& prefix)
0197 {
0198 return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
0199 }
0200
0201 template<typename SinglePassRange, typename Sep>
0202 inline boost::range_detail::formatted_range<
0203 typename boost::range_iterator<const SinglePassRange>::type,
0204 Sep, char, char
0205 >
0206 format(const SinglePassRange& rng, const Sep& sep)
0207 {
0208 return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
0209 }
0210
0211 template<typename SinglePassRange>
0212 inline boost::range_detail::formatted_range<
0213 typename boost::range_iterator<const SinglePassRange>::type,
0214 char, char, char
0215 >
0216 format(const SinglePassRange& rng)
0217 {
0218 return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
0219 }
0220
0221 }
0222
0223 namespace range
0224 {
0225 using boost::range_detail::formatted_range;
0226 }
0227 }
0228
0229 #endif