]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/pfr/io_fields.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / pfr / io_fields.hpp
1 // Copyright (c) 2016-2022 Antony Polukhin
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
7 #ifndef BOOST_PFR_IO_FIELDS_HPP
8 #define BOOST_PFR_IO_FIELDS_HPP
9 #pragma once
10
11 #include <boost/pfr/detail/config.hpp>
12
13 #include <boost/pfr/detail/core.hpp>
14
15 #include <type_traits>
16 #include <utility> // metaprogramming stuff
17
18 #include <boost/pfr/detail/sequence_tuple.hpp>
19 #include <boost/pfr/detail/io.hpp>
20 #include <boost/pfr/detail/make_integer_sequence.hpp>
21 #include <boost/pfr/tuple_size.hpp>
22
23 /// \file boost/pfr/io_fields.hpp
24 /// Contains IO manupulator \forcedlink{io_fields} to read/write \aggregate `value` field-by-field.
25 ///
26 /// \b Example:
27 /// \code
28 /// struct my_struct {
29 /// int i;
30 /// short s;
31 /// };
32 ///
33 /// std::ostream& operator<<(std::ostream& os, const my_struct& x) {
34 /// return os << boost::pfr::io_fields(x); // Equivalent to: os << "{ " << x.i << " ," << x.s << " }"
35 /// }
36 ///
37 /// std::istream& operator>>(std::istream& is, my_struct& x) {
38 /// return is >> boost::pfr::io_fields(x); // Equivalent to: is >> "{ " >> x.i >> " ," >> x.s >> " }"
39 /// }
40 /// \endcode
41 ///
42 /// \podops for other ways to define operators and more details.
43 ///
44 /// \b Synopsis:
45
46 namespace boost { namespace pfr {
47
48 namespace detail {
49
50 template <class T>
51 struct io_fields_impl {
52 T value;
53 };
54
55
56 template <class Char, class Traits, class T>
57 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<const T&>&& x) {
58 const T& value = x.value;
59 constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
60 out << '{';
61 #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
62 detail::print_impl<0, fields_count_val>::print(out, detail::tie_as_tuple(value));
63 #else
64 ::boost::pfr::detail::for_each_field_dispatcher(
65 value,
66 [&out](const auto& val) {
67 // We can not reuse `fields_count_val` in lambda because compilers had issues with
68 // passing constexpr variables into lambdas. Computing is again is the most portable solution.
69 constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
70 detail::print_impl<0, fields_count_val_lambda>::print(out, val);
71 },
72 detail::make_index_sequence<fields_count_val>{}
73 );
74 #endif
75 return out << '}';
76 }
77
78
79 template <class Char, class Traits, class T>
80 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<T>&& x) {
81 return out << io_fields_impl<const std::remove_reference_t<T>&>{x.value};
82 }
83
84 template <class Char, class Traits, class T>
85 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T&>&& x) {
86 T& value = x.value;
87 constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
88
89 const auto prev_exceptions = in.exceptions();
90 in.exceptions( typename std::basic_istream<Char, Traits>::iostate(0) );
91 const auto prev_flags = in.flags( typename std::basic_istream<Char, Traits>::fmtflags(0) );
92
93 char parenthis = {};
94 in >> parenthis;
95 if (parenthis != '{') in.setstate(std::basic_istream<Char, Traits>::failbit);
96
97 #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
98 detail::read_impl<0, fields_count_val>::read(in, detail::tie_as_tuple(value));
99 #else
100 ::boost::pfr::detail::for_each_field_dispatcher(
101 value,
102 [&in](const auto& val) {
103 // We can not reuse `fields_count_val` in lambda because compilers had issues with
104 // passing constexpr variables into lambdas. Computing is again is the most portable solution.
105 constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
106 detail::read_impl<0, fields_count_val_lambda>::read(in, val);
107 },
108 detail::make_index_sequence<fields_count_val>{}
109 );
110 #endif
111
112 in >> parenthis;
113 if (parenthis != '}') in.setstate(std::basic_istream<Char, Traits>::failbit);
114
115 in.flags(prev_flags);
116 in.exceptions(prev_exceptions);
117
118 return in;
119 }
120
121 template <class Char, class Traits, class T>
122 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<const T&>&& ) {
123 static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped type T with const qualifier.");
124 return in;
125 }
126
127 template <class Char, class Traits, class T>
128 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T>&& ) {
129 static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped temporary of type T.");
130 return in;
131 }
132
133 } // namespace detail
134
135 /// IO manupulator to read/write \aggregate `value` field-by-field.
136 ///
137 /// \b Example:
138 /// \code
139 /// struct my_struct {
140 /// int i;
141 /// short s;
142 /// };
143 ///
144 /// std::ostream& operator<<(std::ostream& os, const my_struct& x) {
145 /// return os << boost::pfr::io_fields(x); // Equivalent to: os << "{ " << x.i << " ," << x.s << " }"
146 /// }
147 ///
148 /// std::istream& operator>>(std::istream& is, my_struct& x) {
149 /// return is >> boost::pfr::io_fields(x); // Equivalent to: is >> "{ " >> x.i >> " ," >> x.s >> " }"
150 /// }
151 /// \endcode
152 ///
153 /// Input and output streaming operators for `boost::pfr::io_fields` are symmetric, meaning that you get the original value by streaming it and
154 /// reading back if each fields streaming operator is symmetric.
155 ///
156 /// \customio
157 template <class T>
158 auto io_fields(T&& value) noexcept {
159 return detail::io_fields_impl<T>{std::forward<T>(value)};
160 }
161
162 }} // namespace boost::pfr
163
164 #endif // BOOST_PFR_IO_FIELDS_HPP