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