diff --git a/doc/uuid/changes.adoc b/doc/uuid/changes.adoc index 54f0da7..e09f654 100644 --- a/doc/uuid/changes.adoc +++ b/doc/uuid/changes.adoc @@ -30,3 +30,4 @@ * Added `uuid_clock`, a ``-compatible clock with an epoch and a resolution as specified in RFC 4122. * Accessors for the timestamp, the time point, the clock sequence, and the node identifier have been added to `uuid`. * Improved the `what()` strings of the `std::runtime_error` exceptions thrown by `string_generator`. +* Added an overload of `to_chars` taking `wchar_t* first, wchar_t* last`. diff --git a/doc/uuid/uuid_io.adoc b/doc/uuid/uuid_io.adoc index ad6d9b4..dfba15f 100644 --- a/doc/uuid/uuid_io.adoc +++ b/doc/uuid/uuid_io.adoc @@ -10,18 +10,27 @@ namespace boost { namespace uuids { -template - std::basic_ostream& - operator<<( std::basic_ostream &os, uuid const& u ); +// stream insertion -template - std::basic_istream& - operator>>( std::basic_istream &is, uuid& u ); +template + std::basic_ostream& + operator<<( std::basic_ostream& os, uuid const& u ); + +// stream extraction + +template + std::basic_istream& + operator>>( std::basic_istream& is, uuid& u ); + +// to_chars template OutputIterator to_chars( uuid const& u, OutputIterator out ); -bool to_chars( uuid const& u, char* first, char* last ); +bool to_chars( uuid const& u, char* first, char* last ) noexcept; +bool to_chars( uuid const& u, wchar_t* first, wchar_t* last ) noexcept; + +// to_string std::string to_string( uuid const& u ); std::wstring to_wstring( uuid const& u ); @@ -29,12 +38,57 @@ std::wstring to_wstring( uuid const& u ); }} // namespace boost::uuids ---- -=== Stream Operators +=== Stream Insertion -The standard input and output stream operators `<<` and `>>` are provided by including `boost/uuid/uuid_io.hpp`. -The string representation of a `uuid` is `hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh` where `h` is a hexadecimal digit. +``` +template + std::basic_ostream& + operator<<( std::basic_ostream& os, uuid const& u ); +``` -```c++ +Requires: :: `Ch` must be either `char` or `wchar_t`. + +Effects: :: Inserts the string representation of `u` into the output stream `os`. ++ +The string representation of a `uuid` is `hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh`, where `h` is a lowercase hexadecimal digit. + +NOTE: This operator also enables the use of + https://www.boost.org/doc/libs/release/doc/html/boost_lexical_cast/synopsis.html[boost::lexical_cast] + to convert a `uuid` to a string. + +Example: :: ++ +``` +using namespace boost::uuids; + +uuid u1 = random_generator()(); + +std::cout << u1 << std::endl; + +std::string s1 = boost::lexical_cast( u1 ); + +std::cout << s1 << std::endl; +``` + +=== Stream Extraction + +``` +template + std::basic_istream& + operator>>( std::basic_istream& is, uuid& u ); +``` + +Requires: :: `Ch` must be either `char` or `wchar_t`. + +Effects: :: Parses a `uuid` string representation from `is` and stores the result into `u`. + +NOTE: This operator also enables the use of + https://www.boost.org/doc/libs/release/doc/html/boost_lexical_cast/synopsis.html[boost::lexical_cast] + to convert a string to a `uuid`. + +Example: :: ++ +``` using namespace boost::uuids; uuid u1 = random_generator()(); @@ -42,49 +96,78 @@ uuid u1 = random_generator()(); std::stringstream ss; ss << u1; -uuid u2; -ss >> u2; +uuid u2 = boost::lexical_cast( ss.str() ); assert( u1 == u2 ); -``` -One can also use https://www.boost.org/doc/libs/release/doc/html/boost_lexical_cast/synopsis.html[boost::lexical_cast]. +uuid u3; +ss >> u3; -```c++ -using namespace boost::uuids; - -uuid u1 = random_generator()(); - -std::string s = boost::lexical_cast( u1 ); -uuid u2 = boost::lexical_cast( s ); - -assert( u1 == u2 ); +assert( u1 == u3 ); ``` === to_chars -The function `to_chars` is a fast non-allocating (and non-throwing if the iterator does not throw) function to write a `uuid` to a string buffer. -It writes exactly 36 characters to the iterator on success (not null-terminated). +``` +template + OutputIterator to_chars( uuid const& u, OutputIterator out ); +``` -```c++ +Effects: :: Outputs the string representation of `u` (exactly 36 characters of type `char`) to the output iterator `out`. + +Example: :: ++ +``` +using namespace boost::uuids; + +uuid u1 = random_generator()(); + +std::vector v; + +to_chars( u1, std::back_inserter( v ) ); +``` + +``` +bool to_chars( uuid const& u, char* first, char* last ) noexcept; +``` +``` +bool to_chars( uuid const& u, wchar_t* first, wchar_t* last ) noexcept; +``` + +Effects: :: If `last - first >= 36`, writes the string representation of `u` (exactly 36 characters, not null terminated) into the buffer starting at `first` and returns `true`. Otherwise, returns `false`. + +Example: :: ++ +``` using namespace boost::uuids; uuid u = random_generator()(); char buf[ 36 ]; -to_chars( u, buf ); -// OR -bool ret = to_chars( u, std::begin(buf), std::end(buf) ); +bool ret = to_chars( u, std::begin( buf ), std::end( buf ) ); assert( ret ); + +std::cout << std::string( buf, 36 ) << std::endl; ``` === to_string The functions `to_string` and `to_wstring` are provided as a convenience to convert a `uuid` to a string. -They are also likely faster than the stream operators or using https://www.boost.org/doc/libs/release/doc/html/boost_lexical_cast/synopsis.html[boost::lexical_cast]. +They are likely to be more efficient than https://www.boost.org/doc/libs/release/doc/html/boost_lexical_cast/synopsis.html[boost::lexical_cast]. -```c++ +``` +std::string to_string( uuid const& u ); +``` +``` +std::wstring to_wstring( uuid const& u ); +``` + +Returns: :: A string containing the string representation of `u`. + +Example: :: ++ +``` using namespace boost::uuids; uuid u = random_generator()(); diff --git a/include/boost/uuid/uuid_io.hpp b/include/boost/uuid/uuid_io.hpp index 6baaa05..d33ab1e 100644 --- a/include/boost/uuid/uuid_io.hpp +++ b/include/boost/uuid/uuid_io.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(_MSC_VER) #pragma warning(push) // Save warning settings. @@ -24,7 +25,7 @@ namespace uuids { namespace detail { -inline char to_char( unsigned i ) +inline char to_char( unsigned i ) noexcept { if( i <= 9 ) { @@ -37,7 +38,7 @@ inline char to_char( unsigned i ) } } -inline wchar_t to_wchar( unsigned i ) +inline wchar_t to_wchar( unsigned i ) noexcept { if( i <= 9 ) { @@ -49,7 +50,7 @@ inline wchar_t to_wchar( unsigned i ) } } -inline char* to_chars( uuid const& u, char* out ) +inline char* to_chars( uuid const& u, char* out ) noexcept { std::size_t i = 0; @@ -70,7 +71,7 @@ inline char* to_chars( uuid const& u, char* out ) return out; } -inline wchar_t* to_chars( uuid const& u, wchar_t* out ) +inline wchar_t* to_chars( uuid const& u, wchar_t* out ) noexcept { std::size_t i = 0; @@ -102,7 +103,7 @@ OutputIterator to_chars( uuid const& u, OutputIterator out ) return std::copy_n( tmp, 36, out ); } -inline bool to_chars( uuid const& u, char* first, char* last ) +inline bool to_chars( uuid const& u, char* first, char* last ) noexcept { if( last - first < 36 ) { @@ -113,7 +114,7 @@ inline bool to_chars( uuid const& u, char* first, char* last ) return true; } -inline bool to_chars( uuid const& u, wchar_t* first, wchar_t* last ) +inline bool to_chars( uuid const& u, wchar_t* first, wchar_t* last ) noexcept { if( last - first < 36 ) {