Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:27

0001 /*
0002  *             Copyright Andrey Semashev 2020.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          https://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   utility/manipulators/range.hpp
0009  * \author Andrey Semashev
0010  * \date   11.05.2020
0011  *
0012  * The header contains implementation of a stream manipulator for inserting a range of elements, optionally separated with a delimiter.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_MANIPULATORS_RANGE_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_MANIPULATORS_RANGE_HPP_INCLUDED_
0017 
0018 #include <cstddef>
0019 #include <boost/range/begin.hpp>
0020 #include <boost/range/end.hpp>
0021 #include <boost/range/const_iterator.hpp>
0022 #include <boost/core/enable_if.hpp>
0023 #include <boost/type_traits/is_scalar.hpp>
0024 #include <boost/type_traits/conditional.hpp>
0025 #include <boost/log/detail/config.hpp>
0026 #include <boost/log/detail/is_ostream.hpp>
0027 #include <boost/log/detail/header.hpp>
0028 
0029 #ifdef BOOST_HAS_PRAGMA_ONCE
0030 #pragma once
0031 #endif
0032 
0033 namespace boost {
0034 
0035 BOOST_LOG_OPEN_NAMESPACE
0036 
0037 /*!
0038  * Stream manipulator for inserting a range of elements, optionally separated with a delimiter.
0039  */
0040 template< typename RangeT, typename DelimiterT >
0041 class range_manipulator
0042 {
0043 private:
0044     typedef typename conditional<
0045         is_scalar< DelimiterT >::value,
0046         DelimiterT,
0047         DelimiterT const&
0048     >::type stored_delimiter_type;
0049 
0050 private:
0051     RangeT const& m_range;
0052     stored_delimiter_type m_delimiter;
0053 
0054 public:
0055     //! Initializing constructor
0056     range_manipulator(RangeT const& range, stored_delimiter_type delimiter) BOOST_NOEXCEPT :
0057         m_range(range),
0058         m_delimiter(delimiter)
0059     {
0060     }
0061 
0062     //! The method outputs elements of the range separated with delimiter
0063     template< typename StreamT >
0064     void output(StreamT& stream) const
0065     {
0066         typedef typename boost::range_const_iterator< RangeT >::type const_iterator;
0067         const_iterator it = boost::begin(m_range);
0068         const const_iterator end = boost::end(m_range);
0069         if (BOOST_LIKELY(it != end))
0070         {
0071             stream << *it;
0072 
0073             for (++it; it != end; ++it)
0074             {
0075                 stream << m_delimiter;
0076                 stream << *it;
0077             }
0078         }
0079     }
0080 };
0081 
0082 /*!
0083  * Stream manipulator for inserting a range of elements. Specialization for when there is no delimiter.
0084  */
0085 template< typename RangeT >
0086 class range_manipulator< RangeT, void >
0087 {
0088 private:
0089     RangeT const& m_range;
0090 
0091 public:
0092     //! Initializing constructor
0093     explicit range_manipulator(RangeT const& range) BOOST_NOEXCEPT :
0094         m_range(range)
0095     {
0096     }
0097 
0098     //! The method outputs elements of the range
0099     template< typename StreamT >
0100     void output(StreamT& stream) const
0101     {
0102         typedef typename boost::range_const_iterator< RangeT >::type const_iterator;
0103         const_iterator it = boost::begin(m_range);
0104         const const_iterator end = boost::end(m_range);
0105         for (; it != end; ++it)
0106         {
0107             stream << *it;
0108         }
0109     }
0110 };
0111 
0112 /*!
0113  * Stream output operator for \c range_manipulator. Outputs every element of the range, separated with a delimiter, if one was specified on manipulator construction.
0114  */
0115 template< typename StreamT, typename RangeT, typename DelimiterT >
0116 inline typename boost::enable_if_c< log::aux::is_ostream< StreamT >::value, StreamT& >::type operator<< (StreamT& strm, range_manipulator< RangeT, DelimiterT > const& manip)
0117 {
0118     if (BOOST_LIKELY(strm.good()))
0119         manip.output(strm);
0120 
0121     return strm;
0122 }
0123 
0124 /*!
0125  * Range manipulator generator function.
0126  *
0127  * \param range Range of elements to output. The range must support begin and end iterators, and its elements must support stream output.
0128  * \param delimiter Delimiter to separate elements in the output. Optional. If not specified, elements are output without separation.
0129  * \returns Manipulator to be inserted into the stream.
0130  *
0131  * \note Both \a range and \a delimiter objects must outlive the created manipulator object.
0132  */
0133 template< typename RangeT, typename DelimiterT >
0134 inline typename boost::enable_if_c<
0135     is_scalar< DelimiterT >::value,
0136     range_manipulator< RangeT, DelimiterT >
0137 >::type range_manip(RangeT const& range, DelimiterT delimiter) BOOST_NOEXCEPT
0138 {
0139     return range_manipulator< RangeT, DelimiterT >(range, delimiter);
0140 }
0141 
0142 /*!
0143  * Range manipulator generator function.
0144  *
0145  * \param range Range of elements to output. The range must support begin and end iterators, and its elements must support stream output.
0146  * \param delimiter Delimiter to separate elements in the output. Optional. If not specified, elements are output without separation.
0147  * \returns Manipulator to be inserted into the stream.
0148  *
0149  * \note Both \a range and \a delimiter objects must outlive the created manipulator object.
0150  */
0151 template< typename RangeT, typename DelimiterT >
0152 inline typename boost::disable_if_c<
0153     is_scalar< DelimiterT >::value,
0154     range_manipulator< RangeT, DelimiterT >
0155 >::type range_manip(RangeT const& range, DelimiterT const& delimiter) BOOST_NOEXCEPT
0156 {
0157     return range_manipulator< RangeT, DelimiterT >(range, delimiter);
0158 }
0159 
0160 /*!
0161  * Range manipulator generator function.
0162  *
0163  * \param range Range of elements to output. The range must support begin and end iterators, and its elements must support stream output.
0164  * \param delimiter Delimiter to separate elements in the output. Optional. If not specified, elements are output without separation.
0165  * \returns Manipulator to be inserted into the stream.
0166  *
0167  * \note Both \a range and \a delimiter objects must outlive the created manipulator object.
0168  */
0169 template< typename RangeT, typename DelimiterElementT, std::size_t N >
0170 inline range_manipulator< RangeT, DelimiterElementT* > range_manip(RangeT const& range, DelimiterElementT (&delimiter)[N]) BOOST_NOEXCEPT
0171 {
0172     return range_manipulator< RangeT, DelimiterElementT* >(range, delimiter);
0173 }
0174 
0175 /*!
0176  * Range manipulator generator function.
0177  *
0178  * \param range Range of elements to output. The range must support begin and end iterators, and its elements must support stream output.
0179  * \returns Manipulator to be inserted into the stream.
0180  *
0181  * \note \a delimiter object must outlive the created manipulator object.
0182  */
0183 template< typename RangeT >
0184 inline range_manipulator< RangeT, void > range_manip(RangeT const& range) BOOST_NOEXCEPT
0185 {
0186     return range_manipulator< RangeT, void >(range);
0187 }
0188 
0189 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0190 
0191 } // namespace boost
0192 
0193 #include <boost/log/detail/footer.hpp>
0194 
0195 #endif // BOOST_LOG_UTILITY_MANIPULATORS_RANGE_HPP_INCLUDED_