#ifndef BOOST_UUID_UUID_IO_HPP_INCLUDED #define BOOST_UUID_UUID_IO_HPP_INCLUDED // Copyright 2009 Andy Tompkins // Copyright 2024 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include #include #include #include #include #include #if defined(_MSC_VER) #pragma warning(push) // Save warning settings. #pragma warning(disable : 4996) // Disable deprecated std::ctype::widen, std::copy #endif namespace boost { namespace uuids { // to_chars template OutputIterator to_chars( uuid const& u, OutputIterator out ) { char tmp[ 36 ]; detail::to_chars( u, tmp ); return std::copy_n( tmp, 36, out ); } template inline bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept { if( last - first < 36 ) { return false; } detail::to_chars( u, first ); return true; } template inline Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept { BOOST_UUID_STATIC_ASSERT( N >= 37 ); detail::to_chars( u, buffer + 0 ); buffer[ 36 ] = 0; return buffer + 36; } // only provided for compatibility; deprecated template BOOST_DEPRECATED( "Use Ch[37] instead of Ch[36] to allow for the null terminator" ) inline Ch* to_chars( uuid const& u, Ch (&buffer)[ 36 ] ) noexcept { detail::to_chars( u, buffer + 0 ); return buffer + 36; } // operator<< template std::basic_ostream& operator<<( std::basic_ostream& os, uuid const& u ) { char tmp[ 37 ]; to_chars( u, tmp ); os << tmp; return os; } // operator>> template std::basic_istream& operator>>( std::basic_istream& is, uuid& u ) { Ch tmp[ 37 ] = {}; is.width( 37 ); // required for pre-C++20 if( is >> tmp ) { u = {}; using ctype_t = std::ctype; ctype_t const& ctype = std::use_facet( is.getloc() ); Ch xdigits[ 17 ]; { char szdigits[] = "0123456789ABCDEF-"; ctype.widen( szdigits, szdigits + 17, xdigits ); } Ch* const xdigits_end = xdigits + 16; ctype.toupper( tmp, tmp + 36 ); int j = 0; for( std::size_t i = 0; i < 16; ++i ) { Ch* f = std::find( xdigits, xdigits_end, tmp[ j++ ] ); if( f == xdigits_end ) { is.setstate( std::ios_base::failbit ); return is; } unsigned char byte = static_cast( f - xdigits ); f = std::find( xdigits, xdigits_end, tmp[ j++ ] ); if( f == xdigits_end ) { is.setstate( std::ios_base::failbit ); return is; } byte <<= 4; byte |= static_cast( f - xdigits ); u.data()[ i ] = byte; if( i == 3 || i == 5 || i == 7 || i == 9 ) { if( tmp[ j++ ] != xdigits[ 16 ] ) { is.setstate( std::ios_base::failbit ); return is; } } } } return is; } // to_string inline std::string to_string( uuid const& u ) { std::string result( 36, char() ); // string::data() returns const char* before C++17 detail::to_chars( u, &result[0] ); return result; } inline std::wstring to_wstring( uuid const& u ) { std::wstring result( 36, wchar_t() ); detail::to_chars( u, &result[0] ); return result; } }} //namespace boost::uuids #if defined(_MSC_VER) #pragma warning(pop) // Restore warnings to previous state. #endif #endif // BOOST_UUID_UUID_IO_HPP_INCLUDED