File indexing completed on 2026-08-25 08:52:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifndef BOOST_OUTCOME_IOSTREAM_SUPPORT_RESULT_HPP
0032 #define BOOST_OUTCOME_IOSTREAM_SUPPORT_RESULT_HPP
0033
0034 #include "result.hpp"
0035
0036 #include <iostream>
0037 #include <sstream>
0038
0039 BOOST_OUTCOME_V2_NAMESPACE_BEGIN
0040
0041 namespace detail
0042 {
0043 template <class T> typename std::add_lvalue_reference<T>::type lvalueref() noexcept;
0044
0045 template <template <class, class> class ValueStorage, class T, class E> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<T, E> &v)
0046 {
0047 s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
0048 if(v._status.have_value())
0049 {
0050 s << v._value;
0051 }
0052 if(v._status.have_error())
0053 {
0054 s << v._error;
0055 }
0056 return s;
0057 }
0058 template <template <class, class> class ValueStorage, class E> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<void, E> &v)
0059 {
0060 s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
0061 if(v._status.have_error())
0062 {
0063 s << v._error;
0064 }
0065 return s;
0066 }
0067 template <template <class, class> class ValueStorage, class T> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<T, void> &v)
0068 {
0069 s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
0070 if(v._status.have_value())
0071 {
0072 s << v._value;
0073 }
0074 return s;
0075 }
0076
0077 template <class T, class E> inline std::ostream &operator<<(std::ostream &s, const value_storage_trivial<T, E> &v)
0078 {
0079 return value_storage_out(s, v);
0080 }
0081 template <class T, class E> inline std::ostream &operator<<(std::ostream &s, const value_storage_nontrivial<T, E> &v)
0082 {
0083 return value_storage_out(s, v);
0084 }
0085
0086 template <template <class, class> class ValueStorage, class T, class E> inline std::istream &value_storage_in(std::istream &s, ValueStorage<T, E> &v)
0087 {
0088 using type = ValueStorage<T, E>;
0089 v.~type();
0090 new(&v) type;
0091 uint16_t x, y;
0092 s >> x >> y;
0093 v._status.status_value = static_cast<detail::status>(x);
0094 v._status.spare_storage_value = y;
0095 if(v._status.have_value())
0096 {
0097 new(BOOST_OUTCOME_ADDRESS_OF(v._value)) decltype(v._value)();
0098 s >> v._value;
0099 }
0100 if(v._status.have_error())
0101 {
0102 new(BOOST_OUTCOME_ADDRESS_OF(v._error)) decltype(v._error)();
0103 s >> v._error;
0104 }
0105 return s;
0106 }
0107 template <template <class, class> class ValueStorage, class E> inline std::istream &value_storage_in(std::istream &s, ValueStorage<void, E> &v)
0108 {
0109 using type = ValueStorage<void, E>;
0110 v.~type();
0111 new(&v) type;
0112 uint16_t x, y;
0113 s >> x >> y;
0114 v._status.status_value = static_cast<detail::status>(x);
0115 v._status.spare_storage_value = y;
0116 if(v._status.have_error())
0117 {
0118 new(BOOST_OUTCOME_ADDRESS_OF(v._error)) decltype(v._error)();
0119 s >> v._error;
0120 }
0121 return s;
0122 }
0123 template <template <class, class> class ValueStorage, class T> inline std::istream &value_storage_in(std::istream &s, ValueStorage<T, void> &v)
0124 {
0125 using type = ValueStorage<T, void>;
0126 v.~type();
0127 new(&v) type;
0128 uint16_t x, y;
0129 s >> x >> y;
0130 v._status.status_value = static_cast<detail::status>(x);
0131 v._status.spare_storage_value = y;
0132 if(v._status.have_value())
0133 {
0134 new(BOOST_OUTCOME_ADDRESS_OF(v._value)) decltype(v._value)();
0135 s >> v._value;
0136 }
0137 return s;
0138 }
0139 template <class T, class E> inline std::istream &operator>>(std::istream &s, value_storage_trivial<T, E> &v)
0140 {
0141 return value_storage_in(s, v);
0142 }
0143 template <class T, class E> inline std::istream &operator>>(std::istream &s, value_storage_nontrivial<T, E> &v)
0144 {
0145 return value_storage_in(s, v);
0146 }
0147 BOOST_OUTCOME_TEMPLATE(class T)
0148 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_constructible<std::error_code, T>::value))
0149 inline std::string safe_message(T && )
0150 {
0151 return {};
0152 }
0153 inline std::string safe_message(const std::error_code &ec)
0154 {
0155 return " (" + ec.message() + ")";
0156 }
0157 }
0158
0159
0160
0161
0162 BOOST_OUTCOME_TEMPLATE(class R, class S, class P)
0163 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<R>()),
0164 BOOST_OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<S>()))
0165 inline std::istream &operator>>(std::istream &s, basic_result<R, S, P> &v)
0166 {
0167 s >> v._iostreams_state();
0168 if(v.has_error())
0169 {
0170 s >> v.assume_error();
0171 }
0172 return s;
0173 }
0174
0175
0176
0177 BOOST_OUTCOME_TEMPLATE(class R, class S, class P)
0178 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<R>()),
0179 BOOST_OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<S>()))
0180 inline std::ostream &operator<<(std::ostream &s, const basic_result<R, S, P> &v)
0181 {
0182 s << v._iostreams_state();
0183 if(v.has_error())
0184 {
0185 s << v.assume_error();
0186 }
0187 return s;
0188 }
0189
0190
0191
0192 template <class R, class S, class P> inline std::string print(const basic_result<R, S, P> &v)
0193 {
0194 std::stringstream s;
0195 if(v.has_value())
0196 {
0197 s << v.value();
0198 }
0199 if(v.has_error())
0200 {
0201 s << v.error() << detail::safe_message(v.error());
0202 }
0203 return s.str();
0204 }
0205
0206
0207
0208 template <class S, class P> inline std::string print(const basic_result<void, S, P> &v)
0209 {
0210 std::stringstream s;
0211 if(v.has_value())
0212 {
0213 s << "(+void)";
0214 }
0215 if(v.has_error())
0216 {
0217 s << v.error() << detail::safe_message(v.error());
0218 }
0219 return s.str();
0220 }
0221
0222
0223
0224 template <class R, class P> inline std::string print(const basic_result<R, void, P> &v)
0225 {
0226 std::stringstream s;
0227 if(v.has_value())
0228 {
0229 s << v.value();
0230 }
0231 if(v.has_error())
0232 {
0233 s << "(-void)";
0234 }
0235 return s.str();
0236 }
0237
0238
0239
0240 template <class P> inline std::string print(const basic_result<void, void, P> &v)
0241 {
0242 std::stringstream s;
0243 if(v.has_value())
0244 {
0245 s << "(+void)";
0246 }
0247 if(v.has_error())
0248 {
0249 s << "(-void)";
0250 }
0251 return s.str();
0252 }
0253 BOOST_OUTCOME_V2_NAMESPACE_END
0254
0255 #endif