Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:50:08

0001 // Copyright (c) 2016-2023 Antony Polukhin
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_PFR_IO_HPP
0007 #define BOOST_PFR_IO_HPP
0008 #pragma once
0009 
0010 #include <boost/pfr/detail/config.hpp>
0011 
0012 #include <boost/pfr/detail/detectors.hpp>
0013 #include <boost/pfr/io_fields.hpp>
0014 
0015 /// \file boost/pfr/io.hpp
0016 /// Contains IO stream manipulator \forcedlink{io} for types.
0017 /// If type is streamable using its own operator or its conversion operator, then the types operator is used.
0018 ///
0019 /// \b Example:
0020 /// \code
0021 ///     #include <boost/pfr/io.hpp>
0022 ///     struct comparable_struct {      // No operators defined for that structure
0023 ///         int i; short s; char data[7]; bool bl; int a,b,c,d,e,f;
0024 ///     };
0025 ///     // ...
0026 ///
0027 ///     comparable_struct s1 {0, 1, "Hello", false, 6,7,8,9,10,11};
0028 ///     std::cout << boost::pfr::io(s1);  // Outputs: {0, 1, H, e, l, l, o, , , 0, 6, 7, 8, 9, 10, 11}
0029 /// \endcode
0030 ///
0031 /// \podops for other ways to define operators and more details.
0032 ///
0033 /// \b Synopsis:
0034 namespace boost { namespace pfr {
0035 
0036 namespace detail {
0037 
0038 ///////////////////// Helper typedefs
0039     template <class Stream, class Type>
0040     using enable_not_ostreamable_t = std::enable_if_t<
0041         not_appliable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
0042         Stream&
0043     >;
0044 
0045     template <class Stream, class Type>
0046     using enable_not_istreamable_t = std::enable_if_t<
0047         not_appliable<istreamable_detector, Stream&, Type&>::value,
0048         Stream&
0049     >;
0050 
0051     template <class Stream, class Type>
0052     using enable_ostreamable_t = std::enable_if_t<
0053         !not_appliable<ostreamable_detector, Stream&, const std::remove_reference_t<Type>&>::value,
0054         Stream&
0055     >;
0056 
0057     template <class Stream, class Type>
0058     using enable_istreamable_t = std::enable_if_t<
0059         !not_appliable<istreamable_detector, Stream&, Type&>::value,
0060         Stream&
0061     >;
0062 
0063 ///////////////////// IO impl
0064 
0065 template <class T>
0066 struct io_impl {
0067     T value;
0068 };
0069 
0070 template <class Char, class Traits, class T>
0071 enable_not_ostreamable_t<std::basic_ostream<Char, Traits>, T> operator<<(std::basic_ostream<Char, Traits>& out, io_impl<T>&& x) {
0072     return out << boost::pfr::io_fields(std::forward<T>(x.value));
0073 }
0074 
0075 template <class Char, class Traits, class T>
0076 enable_ostreamable_t<std::basic_ostream<Char, Traits>, T> operator<<(std::basic_ostream<Char, Traits>& out, io_impl<T>&& x) {
0077     return out << x.value;
0078 }
0079 
0080 template <class Char, class Traits, class T>
0081 enable_not_istreamable_t<std::basic_istream<Char, Traits>, T> operator>>(std::basic_istream<Char, Traits>& in, io_impl<T>&& x) {
0082     return in >> boost::pfr::io_fields(std::forward<T>(x.value));
0083 }
0084 
0085 template <class Char, class Traits, class T>
0086 enable_istreamable_t<std::basic_istream<Char, Traits>, T> operator>>(std::basic_istream<Char, Traits>& in, io_impl<T>&& x) {
0087     return in >> x.value;
0088 }
0089 
0090 } // namespace detail
0091 
0092 /// IO manipulator to read/write \aggregate `value` using its IO stream operators or using \forcedlink{io_fields} if operators are not available.
0093 ///
0094 /// \b Example:
0095 /// \code
0096 ///     struct my_struct { int i; short s; };
0097 ///     my_struct x;
0098 ///     std::stringstream ss;
0099 ///     ss << "{ 12, 13 }";
0100 ///     ss >> boost::pfr::io(x);
0101 ///     assert(x.i == 12);
0102 ///     assert(x.s == 13);
0103 /// \endcode
0104 ///
0105 /// \customio
0106 template <class T>
0107 auto io(T&& value) noexcept {
0108     return detail::io_impl<T>{std::forward<T>(value)};
0109 }
0110 
0111 }} // namespace boost::pfr
0112 
0113 #endif // BOOST_PFR_IO_HPP