// Copyright (c) 2016-2021 Antony Polukhin // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PFR_IO_HPP #define BOOST_PFR_IO_HPP #pragma once #include #include #include /// \file boost/pfr/io.hpp /// Contains IO stream manipulator \forcedlink{io} for types. /// If type is streamable using its own operator or its conversion operator, then the types operator is used. /// /// \b Example: /// \code /// #include /// struct comparable_struct { // No operators defined for that structure /// int i; short s; char data[7]; bool bl; int a,b,c,d,e,f; /// }; /// // ... /// /// comparable_struct s1 {0, 1, "Hello", false, 6,7,8,9,10,11}; /// std::cout << boost::pfr::io(s1); // Outputs: {0, 1, H, e, l, l, o, , , 0, 6, 7, 8, 9, 10, 11} /// \endcode /// /// \podops for other ways to define operators and more details. /// /// \b Synopsis: namespace boost { namespace pfr { namespace detail { ///////////////////// Helper typedefs template using enable_not_ostreamable_t = std::enable_if_t< not_appliable&>::value, Stream& >; template using enable_not_istreamable_t = std::enable_if_t< not_appliable::value, Stream& >; template using enable_ostreamable_t = std::enable_if_t< !not_appliable&>::value, Stream& >; template using enable_istreamable_t = std::enable_if_t< !not_appliable::value, Stream& >; ///////////////////// IO impl template struct io_impl { T value; }; template enable_not_ostreamable_t, T> operator<<(std::basic_ostream& out, io_impl&& x) { return out << boost::pfr::io_fields(std::forward(x.value)); } template enable_ostreamable_t, T> operator<<(std::basic_ostream& out, io_impl&& x) { return out << x.value; } template enable_not_istreamable_t, T> operator>>(std::basic_istream& in, io_impl&& x) { return in >> boost::pfr::io_fields(std::forward(x.value)); } template enable_istreamable_t, T> operator>>(std::basic_istream& in, io_impl&& x) { return in >> x.value; } } // namespace detail /// IO manupulator to read/write \aggregate `value` using its IO stream operators or using \forcedlink{io_fields} if operators are not awailable. /// /// \b Example: /// \code /// struct my_struct { int i; short s; }; /// my_struct s; /// std::stringstream ss; /// ss << "{ 12, 13 }"; /// ss >> boost::pfr::io(s); /// assert(s.i == 12); /// assert(s.i == 13); /// \endcode /// /// \customio template auto io(T&& value) noexcept { return detail::io_impl{std::forward(value)}; } }} // namespace boost::pfr #endif // BOOST_PFR_IO_HPP