Chris@102: // Boost.Range library Chris@102: // Chris@102: // Copyright Neil Groves 2014. Chris@102: // Use, modification and distribution is subject to the Boost Software Chris@102: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@102: // http://www.boost.org/LICENSE_1_0.txt) Chris@102: // Chris@102: // For more information, see http://www.boost.org/libs/range/ Chris@102: // Chris@102: #ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED Chris@102: #define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: namespace boost Chris@102: { Chris@102: namespace range_detail Chris@102: { Chris@102: Chris@102: template Chris@102: struct formatted_holder Chris@102: { Chris@102: typedef typename boost::mpl::if_< Chris@102: boost::is_array, Chris@102: const typename boost::remove_extent::type*, Chris@102: Sep Chris@102: >::type separator_t; Chris@102: Chris@102: typedef typename boost::mpl::if_< Chris@102: boost::is_array, Chris@102: const typename boost::remove_extent::type*, Chris@102: Prefix Chris@102: >::type prefix_t; Chris@102: Chris@102: typedef typename boost::mpl::if_< Chris@102: boost::is_array, Chris@102: const typename boost::remove_extent::type*, Chris@102: Postfix Chris@102: >::type postfix_t; Chris@102: Chris@102: formatted_holder( Chris@102: const separator_t& sep, Chris@102: const prefix_t& prefix, Chris@102: const postfix_t& postfix) Chris@102: : m_sep(sep) Chris@102: , m_prefix(prefix) Chris@102: , m_postfix(postfix) Chris@102: { Chris@102: } Chris@102: Chris@102: separator_t m_sep; Chris@102: prefix_t m_prefix; Chris@102: postfix_t m_postfix; Chris@102: }; Chris@102: Chris@102: template Chris@102: class formatted_range Chris@102: : public boost::iterator_range Chris@102: { Chris@102: typedef formatted_holder holder_t; Chris@102: public: Chris@102: formatted_range(Iter first, Iter last, const holder_t& holder) Chris@102: : boost::iterator_range(first, last) Chris@102: , m_holder(holder) Chris@102: { Chris@102: } Chris@102: Chris@102: template Chris@102: void write(OStream& out) const Chris@102: { Chris@102: Iter it(this->begin()); Chris@102: out << m_holder.m_prefix; Chris@102: if (it != this->end()) Chris@102: { Chris@102: out << *it; Chris@102: for (++it; it != this->end(); ++it) Chris@102: { Chris@102: out << m_holder.m_sep << *it; Chris@102: } Chris@102: } Chris@102: out << m_holder.m_postfix; Chris@102: } Chris@102: Chris@102: private: Chris@102: holder_t m_holder; Chris@102: }; Chris@102: Chris@102: template< Chris@102: typename SinglePassRange, Chris@102: typename Sep, Chris@102: typename Prefix, Chris@102: typename Postfix Chris@102: > Chris@102: inline range_detail::formatted_range< Chris@102: typename range_iterator::type, Sep, Prefix, Postfix Chris@102: > Chris@102: operator|( Chris@102: const SinglePassRange& rng, Chris@102: const range_detail::formatted_holder& holder Chris@102: ) Chris@102: { Chris@102: typedef typename range_iterator::type iterator; Chris@102: return range_detail::formatted_range( Chris@102: boost::begin(rng), boost::end(rng), holder); Chris@102: } Chris@102: Chris@102: template Chris@102: std::basic_ostream& Chris@102: operator<<( Chris@102: std::basic_ostream& out, Chris@102: const formatted_range& writer) Chris@102: { Chris@102: writer.write(out); Chris@102: return out; Chris@102: } Chris@102: Chris@102: } // namespace range_detail Chris@102: Chris@102: namespace adaptors Chris@102: { Chris@102: Chris@102: template Chris@102: range_detail::formatted_holder Chris@102: formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix) Chris@102: { Chris@102: return range_detail::formatted_holder( Chris@102: sep, prefix, postfix); Chris@102: } Chris@102: Chris@102: template Chris@102: range_detail::formatted_holder Chris@102: formatted(const Sep& sep, const Prefix& prefix) Chris@102: { Chris@102: return range_detail::formatted_holder(sep, prefix, '}'); Chris@102: } Chris@102: Chris@102: template Chris@102: range_detail::formatted_holder Chris@102: formatted(const Sep& sep) Chris@102: { Chris@102: return range_detail::formatted_holder(sep, '{', '}'); Chris@102: } Chris@102: Chris@102: inline range_detail::formatted_holder Chris@102: formatted() Chris@102: { Chris@102: return range_detail::formatted_holder(',', '{', '}'); Chris@102: } Chris@102: Chris@102: using range_detail::formatted_range; Chris@102: Chris@102: template Chris@102: inline boost::range_detail::formatted_range< Chris@102: typename boost::range_iterator::type, Chris@102: Sep, Prefix, Postfix Chris@102: > Chris@102: format( Chris@102: const SinglePassRange& rng, Chris@102: const Sep& sep, Chris@102: const Prefix& prefix, Chris@102: const Postfix& postfix Chris@102: ) Chris@102: { Chris@102: typedef typename boost::range_iterator::type Chris@102: iterator_t; Chris@102: Chris@102: typedef boost::range_detail::formatted_range< Chris@102: iterator_t, Sep, Prefix, Postfix> result_t; Chris@102: Chris@102: typedef boost::range_detail::formatted_holder Chris@102: holder_t; Chris@102: Chris@102: return result_t(boost::begin(rng), boost::end(rng), Chris@102: holder_t(sep, prefix, postfix)); Chris@102: } Chris@102: Chris@102: template Chris@102: inline boost::range_detail::formatted_range< Chris@102: typename boost::range_iterator::type, Chris@102: Sep, Prefix, char Chris@102: > Chris@102: format( Chris@102: const SinglePassRange& rng, Chris@102: const Sep& sep, Chris@102: const Prefix& prefix) Chris@102: { Chris@102: return adaptors::format(rng, sep, prefix, '}'); Chris@102: } Chris@102: Chris@102: template Chris@102: inline boost::range_detail::formatted_range< Chris@102: typename boost::range_iterator::type, Chris@102: Sep, char, char Chris@102: > Chris@102: format(const SinglePassRange& rng, const Sep& sep) Chris@102: { Chris@102: return adaptors::format(rng, sep, '{', '}'); Chris@102: } Chris@102: Chris@102: template Chris@102: inline boost::range_detail::formatted_range< Chris@102: typename boost::range_iterator::type, Chris@102: char, char, char Chris@102: > Chris@102: format(const SinglePassRange& rng) Chris@102: { Chris@102: return adaptors::format(rng, ',', '{', '}'); Chris@102: } Chris@102: Chris@102: } // namespace adaptors Chris@102: Chris@102: namespace range Chris@102: { Chris@102: using boost::range_detail::formatted_range; Chris@102: } // namespace range Chris@102: } // namespace boost Chris@102: Chris@102: #endif // include guard