File indexing completed on 2025-01-18 09:43:38
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_PFR_IO_FIELDS_HPP
0008 #define BOOST_PFR_IO_FIELDS_HPP
0009 #pragma once
0010
0011 #include <boost/pfr/detail/config.hpp>
0012
0013 #include <boost/pfr/detail/core.hpp>
0014
0015 #include <type_traits>
0016 #include <utility> // metaprogramming stuff
0017
0018 #include <boost/pfr/detail/sequence_tuple.hpp>
0019 #include <boost/pfr/detail/io.hpp>
0020 #include <boost/pfr/detail/make_integer_sequence.hpp>
0021 #include <boost/pfr/tuple_size.hpp>
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 namespace boost { namespace pfr {
0047
0048 namespace detail {
0049
0050 template <class T>
0051 struct io_fields_impl {
0052 T value;
0053 };
0054
0055
0056 template <class Char, class Traits, class T>
0057 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<const T&>&& x) {
0058 const T& value = x.value;
0059 constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
0060 out << '{';
0061 #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
0062 detail::print_impl<0, fields_count_val>::print(out, detail::tie_as_tuple(value));
0063 #else
0064 ::boost::pfr::detail::for_each_field_dispatcher(
0065 value,
0066 [&out](const auto& val) {
0067
0068
0069 constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
0070 detail::print_impl<0, fields_count_val_lambda>::print(out, val);
0071 },
0072 detail::make_index_sequence<fields_count_val>{}
0073 );
0074 #endif
0075 return out << '}';
0076 }
0077
0078
0079 template <class Char, class Traits, class T>
0080 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<T>&& x) {
0081 return out << io_fields_impl<const std::remove_reference_t<T>&>{x.value};
0082 }
0083
0084 template <class Char, class Traits, class T>
0085 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T&>&& x) {
0086 T& value = x.value;
0087 constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
0088
0089 const auto prev_exceptions = in.exceptions();
0090 in.exceptions( typename std::basic_istream<Char, Traits>::iostate(0) );
0091 const auto prev_flags = in.flags( typename std::basic_istream<Char, Traits>::fmtflags(0) );
0092
0093 char parenthis = {};
0094 in >> parenthis;
0095 if (parenthis != '{') in.setstate(std::basic_istream<Char, Traits>::failbit);
0096
0097 #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
0098 detail::read_impl<0, fields_count_val>::read(in, detail::tie_as_tuple(value));
0099 #else
0100 ::boost::pfr::detail::for_each_field_dispatcher(
0101 value,
0102 [&in](const auto& val) {
0103
0104
0105 constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
0106 detail::read_impl<0, fields_count_val_lambda>::read(in, val);
0107 },
0108 detail::make_index_sequence<fields_count_val>{}
0109 );
0110 #endif
0111
0112 in >> parenthis;
0113 if (parenthis != '}') in.setstate(std::basic_istream<Char, Traits>::failbit);
0114
0115 in.flags(prev_flags);
0116 in.exceptions(prev_exceptions);
0117
0118 return in;
0119 }
0120
0121 template <class Char, class Traits, class T>
0122 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<const T&>&& ) {
0123 static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped type T with const qualifier.");
0124 return in;
0125 }
0126
0127 template <class Char, class Traits, class T>
0128 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T>&& ) {
0129 static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped temporary of type T.");
0130 return in;
0131 }
0132
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 template <class T>
0158 auto io_fields(T&& value) noexcept {
0159 return detail::io_fields_impl<T>{std::forward<T>(value)};
0160 }
0161
0162 }}
0163
0164 #endif