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/optional.hpp
0009  * \author Andrey Semashev
0010  * \date   12.05.2020
0011  *
0012  * The header contains implementation of a stream manipulator for inserting an optional value.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_MANIPULATORS_OPTIONAL_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_MANIPULATORS_OPTIONAL_HPP_INCLUDED_
0017 
0018 #include <cstddef>
0019 #include <boost/core/enable_if.hpp>
0020 #include <boost/type_traits/is_array.hpp>
0021 #include <boost/type_traits/is_scalar.hpp>
0022 #include <boost/type_traits/conditional.hpp>
0023 #include <boost/log/detail/config.hpp>
0024 #include <boost/log/detail/is_ostream.hpp>
0025 #include <boost/log/detail/header.hpp>
0026 
0027 #ifdef BOOST_HAS_PRAGMA_ONCE
0028 #pragma once
0029 #endif
0030 
0031 namespace boost {
0032 
0033 BOOST_LOG_OPEN_NAMESPACE
0034 
0035 /*!
0036  * Stream manipulator for inserting an optional value.
0037  */
0038 template< typename OptionalT, typename NoneT >
0039 class optional_manipulator
0040 {
0041 private:
0042     typedef typename conditional<
0043         is_scalar< OptionalT >::value,
0044         OptionalT,
0045         OptionalT const&
0046     >::type stored_optional_type;
0047 
0048     typedef typename conditional<
0049         is_scalar< NoneT >::value,
0050         NoneT,
0051         NoneT const&
0052     >::type stored_none_type;
0053 
0054 private:
0055     stored_optional_type m_optional;
0056     stored_none_type m_none;
0057 
0058 public:
0059     //! Initializing constructor
0060     optional_manipulator(stored_optional_type opt, stored_none_type none) BOOST_NOEXCEPT :
0061         m_optional(opt),
0062         m_none(none)
0063     {
0064     }
0065 
0066     //! The method outputs the value, if it is present, otherwise outputs the "none" marker
0067     template< typename StreamT >
0068     void output(StreamT& stream) const
0069     {
0070         if (!!m_optional)
0071             stream << *m_optional;
0072         else
0073             stream << m_none;
0074     }
0075 };
0076 
0077 /*!
0078  * Stream manipulator for inserting an optional value. Specialization for no "none" marker.
0079  */
0080 template< typename OptionalT >
0081 class optional_manipulator< OptionalT, void >
0082 {
0083 private:
0084     typedef typename conditional<
0085         is_scalar< OptionalT >::value,
0086         OptionalT,
0087         OptionalT const&
0088     >::type stored_optional_type;
0089 
0090 private:
0091     stored_optional_type m_optional;
0092 
0093 public:
0094     //! Initializing constructor
0095     optional_manipulator(stored_optional_type opt) BOOST_NOEXCEPT :
0096         m_optional(opt)
0097     {
0098     }
0099 
0100     //! The method outputs the value, if it is present
0101     template< typename StreamT >
0102     void output(StreamT& stream) const
0103     {
0104         if (!!m_optional)
0105             stream << *m_optional;
0106     }
0107 };
0108 
0109 /*!
0110  * Stream output operator for \c optional_manipulator. Outputs the optional value or the "none" marker, if one was specified on manipulator construction.
0111  */
0112 template< typename StreamT, typename OptionalT, typename NoneT >
0113 inline typename boost::enable_if_c< log::aux::is_ostream< StreamT >::value, StreamT& >::type operator<< (StreamT& strm, optional_manipulator< OptionalT, NoneT > const& manip)
0114 {
0115     manip.output(strm);
0116     return strm;
0117 }
0118 
0119 /*!
0120  * Optional manipulator generator function.
0121  *
0122  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0123  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0124  * \returns Manipulator to be inserted into the stream.
0125  *
0126  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0127  */
0128 template< typename OptionalT, typename NoneT >
0129 inline typename boost::enable_if_c<
0130     is_scalar< OptionalT >::value && is_scalar< NoneT >::value,
0131     optional_manipulator< OptionalT, NoneT >
0132 >::type optional_manip(OptionalT opt, NoneT none) BOOST_NOEXCEPT
0133 {
0134     return optional_manipulator< OptionalT, NoneT >(opt, none);
0135 }
0136 
0137 /*!
0138  * Optional manipulator generator function.
0139  *
0140  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0141  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0142  * \returns Manipulator to be inserted into the stream.
0143  *
0144  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0145  */
0146 template< typename OptionalT, typename NoneT >
0147 inline typename boost::enable_if_c<
0148     is_scalar< OptionalT >::value && !is_scalar< NoneT >::value,
0149     optional_manipulator< OptionalT, NoneT >
0150 >::type optional_manip(OptionalT opt, NoneT const& none) BOOST_NOEXCEPT
0151 {
0152     return optional_manipulator< OptionalT, NoneT >(opt, none);
0153 }
0154 
0155 /*!
0156  * Optional manipulator generator function.
0157  *
0158  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0159  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0160  * \returns Manipulator to be inserted into the stream.
0161  *
0162  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0163  */
0164 template< typename OptionalT, typename NoneElementT, std::size_t N >
0165 inline typename boost::enable_if_c<
0166     is_scalar< OptionalT >::value,
0167     optional_manipulator< OptionalT, NoneElementT* >
0168 >::type optional_manip(OptionalT opt, NoneElementT (&none)[N]) BOOST_NOEXCEPT
0169 {
0170     return optional_manipulator< OptionalT, NoneElementT* >(opt, none);
0171 }
0172 
0173 /*!
0174  * Optional manipulator generator function.
0175  *
0176  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0177  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0178  * \returns Manipulator to be inserted into the stream.
0179  *
0180  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0181  */
0182 template< typename OptionalT, typename NoneT >
0183 inline typename boost::enable_if_c<
0184     !is_scalar< OptionalT >::value && !is_array< OptionalT >::value && is_scalar< NoneT >::value,
0185     optional_manipulator< OptionalT, NoneT >
0186 >::type optional_manip(OptionalT const& opt, NoneT none) BOOST_NOEXCEPT
0187 {
0188     return optional_manipulator< OptionalT, NoneT >(opt, none);
0189 }
0190 
0191 /*!
0192  * Optional manipulator generator function.
0193  *
0194  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0195  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0196  * \returns Manipulator to be inserted into the stream.
0197  *
0198  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0199  */
0200 template< typename OptionalT, typename NoneT >
0201 inline typename boost::enable_if_c<
0202     !is_scalar< OptionalT >::value && !is_array< OptionalT >::value && !is_scalar< NoneT >::value,
0203     optional_manipulator< OptionalT, NoneT >
0204 >::type optional_manip(OptionalT const& opt, NoneT const& none) BOOST_NOEXCEPT
0205 {
0206     return optional_manipulator< OptionalT, NoneT >(opt, none);
0207 }
0208 
0209 /*!
0210  * Optional manipulator generator function.
0211  *
0212  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0213  * \param none Marker used to indicate when the value is not present. Optional. If not specified, nothing is output if the value is not present.
0214  * \returns Manipulator to be inserted into the stream.
0215  *
0216  * \note Both \a opt and \a none objects must outlive the created manipulator object.
0217  */
0218 template< typename OptionalT, typename NoneElementT, std::size_t N >
0219 inline typename boost::enable_if_c<
0220     !is_scalar< OptionalT >::value && !is_array< OptionalT >::value,
0221     optional_manipulator< OptionalT, NoneElementT* >
0222 >::type optional_manip(OptionalT const& opt, NoneElementT (&none)[N]) BOOST_NOEXCEPT
0223 {
0224     return optional_manipulator< OptionalT, NoneElementT* >(opt, none);
0225 }
0226 
0227 /*!
0228  * Optional manipulator generator function.
0229  *
0230  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0231  * \returns Manipulator to be inserted into the stream.
0232  *
0233  * \note \a opt object must outlive the created manipulator object.
0234  */
0235 template< typename OptionalT >
0236 inline typename boost::enable_if_c<
0237     is_scalar< OptionalT >::value,
0238     optional_manipulator< OptionalT, void >
0239 >::type optional_manip(OptionalT opt) BOOST_NOEXCEPT
0240 {
0241     return optional_manipulator< OptionalT, void >(opt);
0242 }
0243 
0244 /*!
0245  * Optional manipulator generator function.
0246  *
0247  * \param opt Optional value to output. The optional value must support contextual conversion to \c bool and dereferencing, and its dereferencing result must support stream output.
0248  * \returns Manipulator to be inserted into the stream.
0249  *
0250  * \note \a opt object must outlive the created manipulator object.
0251  */
0252 template< typename OptionalT >
0253 inline typename boost::enable_if_c<
0254     !is_scalar< OptionalT >::value && !is_array< OptionalT >::value,
0255     optional_manipulator< OptionalT, void >
0256 >::type optional_manip(OptionalT const& opt) BOOST_NOEXCEPT
0257 {
0258     return optional_manipulator< OptionalT, void >(opt);
0259 }
0260 
0261 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0262 
0263 } // namespace boost
0264 
0265 #include <boost/log/detail/footer.hpp>
0266 
0267 #endif // BOOST_LOG_UTILITY_MANIPULATORS_OPTIONAL_HPP_INCLUDED_