123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #ifndef BOOST_PFR_IO_FIELDS_HPP
- #define BOOST_PFR_IO_FIELDS_HPP
- #pragma once
- #include <boost/pfr/detail/config.hpp>
- #include <boost/pfr/detail/core.hpp>
- #include <type_traits>
- #include <utility>
- #include <boost/pfr/detail/sequence_tuple.hpp>
- #include <boost/pfr/detail/io.hpp>
- #include <boost/pfr/detail/make_integer_sequence.hpp>
- #include <boost/pfr/tuple_size.hpp>
- namespace boost { namespace pfr {
- namespace detail {
- template <class T>
- struct io_fields_impl {
- T value;
- };
- template <class Char, class Traits, class T>
- std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<const T&>&& x) {
- const T& value = x.value;
- constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
- out << '{';
- #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
- detail::print_impl<0, fields_count_val>::print(out, detail::tie_as_tuple(value));
- #else
- ::boost::pfr::detail::for_each_field_dispatcher(
- value,
- [&out](const auto& val) {
-
-
- constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
- detail::print_impl<0, fields_count_val_lambda>::print(out, val);
- },
- detail::make_index_sequence<fields_count_val>{}
- );
- #endif
- return out << '}';
- }
- template <class Char, class Traits, class T>
- std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, io_fields_impl<T>&& x) {
- return out << io_fields_impl<const std::remove_reference_t<T>&>{x.value};
- }
- template <class Char, class Traits, class T>
- std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T&>&& x) {
- T& value = x.value;
- constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<T>();
- const auto prev_exceptions = in.exceptions();
- in.exceptions( typename std::basic_istream<Char, Traits>::iostate(0) );
- const auto prev_flags = in.flags( typename std::basic_istream<Char, Traits>::fmtflags(0) );
- char parenthis = {};
- in >> parenthis;
- if (parenthis != '{') in.setstate(std::basic_istream<Char, Traits>::failbit);
- #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
- detail::read_impl<0, fields_count_val>::read(in, detail::tie_as_tuple(value));
- #else
- ::boost::pfr::detail::for_each_field_dispatcher(
- value,
- [&in](const auto& val) {
-
-
- constexpr std::size_t fields_count_val_lambda = boost::pfr::detail::fields_count<T>();
- detail::read_impl<0, fields_count_val_lambda>::read(in, val);
- },
- detail::make_index_sequence<fields_count_val>{}
- );
- #endif
- in >> parenthis;
- if (parenthis != '}') in.setstate(std::basic_istream<Char, Traits>::failbit);
- in.flags(prev_flags);
- in.exceptions(prev_exceptions);
- return in;
- }
- template <class Char, class Traits, class T>
- std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<const T&>&& ) {
- static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped type T with const qualifier.");
- return in;
- }
- template <class Char, class Traits, class T>
- std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& in, io_fields_impl<T>&& ) {
- static_assert(sizeof(T) && false, "====================> Boost.PFR: Attempt to use istream operator on a boost::pfr::io_fields wrapped temporary of type T.");
- return in;
- }
- }
- template <class T>
- auto io_fields(T&& value) noexcept {
- return detail::io_fields_impl<T>{std::forward<T>(value)};
- }
- }}
- #endif
|