Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63941 - in branches/release: boost/uuid libs/uuid libs/uuid/test
From: atompkins_at_[hidden]
Date: 2010-07-12 20:37:19


Author: atompkins
Date: 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
New Revision: 63941
URL: http://svn.boost.org/trac/boost/changeset/63941

Log:
One can define BOOST_UUID_NO_TYPE_TRAITS to remove the dependency on Boost.TypeTraits.
Stream operator<< handles left, internal, and right manipulators.
Added to_string, to_wstring
Fixed bug in 3 uuid string in documentation

Text files modified:
   branches/release/boost/uuid/uuid.hpp | 9 ++-
   branches/release/boost/uuid/uuid_io.hpp | 81 ++++++++++++++++++++++++++++++++++
   branches/release/libs/uuid/test/Jamfile.v2 | 4
   branches/release/libs/uuid/test/compile_uuid.cpp | 2
   branches/release/libs/uuid/test/test_io.cpp | 93 +++++++++++++++++++++++++++++++++++++++
   branches/release/libs/uuid/uuid.html | 63 +++++++++++++++++++++-----
   6 files changed, 231 insertions(+), 21 deletions(-)

Modified: branches/release/boost/uuid/uuid.hpp
==============================================================================
--- branches/release/boost/uuid/uuid.hpp (original)
+++ branches/release/boost/uuid/uuid.hpp 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -37,8 +37,10 @@
 #include <boost/cstdint.hpp>
 #include <algorithm>
 #include <boost/config.hpp> // for static assert
-#include <boost/mpl/bool.hpp>
+#ifndef BOOST_UUID_NO_TYPE_TRAITS
 #include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#endif
 
 #if defined(_MSC_VER)
 #pragma warning(push) // Save warning settings.
@@ -202,14 +204,15 @@
 
 }} //namespace boost::uuids
 
+#ifndef BOOST_UUID_NO_TYPE_TRAITS
 // type traits specializations
 namespace boost {
 
 template <>
-struct is_pod<uuids::uuid> : mpl::true_
-{};
+struct is_pod<uuids::uuid> : true_type {};
 
 } // namespace boost
+#endif
 
 #if defined(_MSC_VER)
 #pragma warning(pop) // Restore warnings to previous state.

Modified: branches/release/boost/uuid/uuid_io.hpp
==============================================================================
--- branches/release/boost/uuid/uuid_io.hpp (original)
+++ branches/release/boost/uuid/uuid_io.hpp 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -32,11 +32,20 @@
     std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u)
 {
     io::ios_flags_saver flags_saver(os);
- io::ios_width_saver width_saver(os);
     io::basic_ios_fill_saver<ch, char_traits> fill_saver(os);
 
     const typename std::basic_ostream<ch, char_traits>::sentry ok(os);
     if (ok) {
+ const std::streamsize width = os.width(0);
+ const std::streamsize uuid_width = 36;
+ const std::ios_base::fmtflags flags = os.flags();
+ const typename std::basic_ios<ch, char_traits>::char_type fill = os.fill();
+ if (flags & (std::ios_base::right | std::ios_base::internal)) {
+ for (std::streamsize i=uuid_width; i<width; i++) {
+ os << fill;
+ }
+ }
+
         os << std::hex;
         os.fill(os.widen('0'));
 
@@ -48,6 +57,14 @@
                 os << os.widen('-');
             }
         }
+
+ if (flags & std::ios_base::left) {
+ for (std::streamsize i=uuid_width; i<width; i++) {
+ os << fill;
+ }
+ }
+
+ os.width(0); //used the width so reset it
     }
     return os;
 }
@@ -110,6 +127,68 @@
     return is;
 }
 
+namespace detail {
+inline char to_char(size_t i) {
+ if (i <= 9) {
+ return static_cast<char>('0' + i);
+ } else {
+ return static_cast<char>('a' + (i-10));
+ }
+}
+
+inline wchar_t to_wchar(size_t i) {
+ if (i <= 9) {
+ return static_cast<wchar_t>(L'0' + i);
+ } else {
+ return static_cast<wchar_t>(L'a' + (i-10));
+ }
+}
+
+} // namespace detail
+
+inline std::string to_string(uuid const& u)
+{
+ std::string result;
+ result.reserve(36);
+
+ std::size_t i=0;
+ for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
+ const size_t hi = ((*it_data) >> 4) & 0x0F;
+ result += detail::to_char(hi);
+
+ const size_t lo = (*it_data) & 0x0F;
+ result += detail::to_char(lo);
+
+ if (i == 3 || i == 5 || i == 7 || i == 9) {
+ result += '-';
+ }
+ }
+ return result;
+}
+
+#ifndef BOOST_NO_STD_WSTRING
+inline std::wstring to_wstring(uuid const& u)
+{
+ std::wstring result;
+ result.reserve(36);
+
+ std::size_t i=0;
+ for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
+ const size_t hi = ((*it_data) >> 4) & 0x0F;
+ result += detail::to_wchar(hi);
+
+ const size_t lo = (*it_data) & 0x0F;
+ result += detail::to_wchar(lo);
+
+ if (i == 3 || i == 5 || i == 7 || i == 9) {
+ result += L'-';
+ }
+ }
+ return result;
+}
+
+#endif
+
 }} //namespace boost::uuids
 
 #if defined(_MSC_VER)

Modified: branches/release/libs/uuid/test/Jamfile.v2
==============================================================================
--- branches/release/libs/uuid/test/Jamfile.v2 (original)
+++ branches/release/libs/uuid/test/Jamfile.v2 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -8,6 +8,7 @@
 test-suite uuid :
     # make sure each header file is self-contained
     [ compile compile_uuid.cpp ]
+ [ compile compile_uuid.cpp : <define>BOOST_UUID_NO_TYPE_TRAITS : compile_uuid_no_type_traits ]
     [ compile compile_uuid_io.cpp ]
     [ compile compile_uuid_serialize.cpp ]
     [ compile compile_uuid_generators.cpp ]
@@ -40,8 +41,7 @@
     [ run test_uuid_class.cpp ]
 
     # test serializing uuids
- [ run test_serialization.cpp ../../serialization/build//boost_serialization
- ]
+ [ run test_serialization.cpp ../../serialization/build//boost_serialization ]
     # TODO - This test fails to like with boost_wserialization
     #[ run test_wserialization.cpp
     # ../../serialization/build//boost_serialization

Modified: branches/release/libs/uuid/test/compile_uuid.cpp
==============================================================================
--- branches/release/libs/uuid/test/compile_uuid.cpp (original)
+++ branches/release/libs/uuid/test/compile_uuid.cpp 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -7,7 +7,7 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-// Purpose to make sure that a translation unit consisting of just the contents
+// Purpose to make sure that a translation unit consisting of just the contents
 // of the header file will compile successfully.
 
 #include <boost/uuid/uuid.hpp>

Modified: branches/release/libs/uuid/test/test_io.cpp
==============================================================================
--- branches/release/libs/uuid/test/test_io.cpp (original)
+++ branches/release/libs/uuid/test/test_io.cpp 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -15,6 +15,20 @@
 
 #include <boost/lexical_cast.hpp>
 #include <string>
+#include <sstream>
+#include <iomanip>
+
+#ifndef BOOST_NO_STD_WSTRING
+namespace std {
+template <typename Elem, typename Traits>
+std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& os, std::wstring const& s) {
+ // convert to string
+ std::string temp(s.begin(), s.end());
+ os << temp;
+ return os;
+}
+} // namespace std
+#endif
 
 int main(int, char*[])
 {
@@ -36,8 +50,48 @@
         std::stringstream ss3;
         ss3 << u3;
         BOOST_TEST_EQ(ss3.str(), "12345678-90ab-cdef-1234-567890abcdef");
+
+ std::stringstream ss4;
+ ss4 << std::uppercase << u3;
+ BOOST_TEST_EQ(ss4.str(), "12345678-90AB-CDEF-1234-567890ABCDEF");
+
+ std::stringstream ss5;
+ ss5 << 'a' << std::right << std::setfill('*') << std::setw(40) << u1 << 'a';
+ BOOST_TEST_EQ(ss5.str(), "a****00000000-0000-0000-0000-000000000000a");
+
+ std::stringstream ss6;
+ ss6 << std::left << std::setfill('*') << std::setw(45) << u1;
+ BOOST_TEST_EQ(ss6.str(), "00000000-0000-0000-0000-000000000000*********");
     }
 
+ #ifndef BOOST_NO_STD_WSTRING
+ { // test insert/extract operators
+ std::wstringstream ss1;
+ ss1 << u1;
+ BOOST_TEST_EQ(ss1.str(), L"00000000-0000-0000-0000-000000000000");
+
+ std::wstringstream ss2;
+ ss2 << u2;
+ BOOST_TEST_EQ(ss2.str(), L"00010203-0405-0607-0809-0a0b0c0d0e0f");
+
+ std::wstringstream ss3;
+ ss3 << u3;
+ BOOST_TEST_EQ(ss3.str(), L"12345678-90ab-cdef-1234-567890abcdef");
+
+ std::wstringstream ss4;
+ ss4 << std::uppercase << u3;
+ BOOST_TEST_EQ(ss4.str(), L"12345678-90AB-CDEF-1234-567890ABCDEF");
+
+ std::wstringstream ss5;
+ ss5 << L'a' << std::right << std::setfill(L'*') << std::setw(40) << u1 << L'a';
+ BOOST_TEST_EQ(ss5.str(), L"a****00000000-0000-0000-0000-000000000000a");
+
+ std::wstringstream ss6;
+ ss6 << std::left << std::setfill(L'*') << std::setw(45) << u1;
+ BOOST_TEST_EQ(ss6.str(), L"00000000-0000-0000-0000-000000000000*********");
+ }
+#endif
+
     {
         uuid u;
 
@@ -51,6 +105,21 @@
         BOOST_TEST_EQ(u, u3);
     }
 
+ #ifndef BOOST_NO_STD_WSTRING
+ {
+ uuid u;
+
+ std::wstringstream ss;
+ ss << L"00000000-0000-0000-0000-000000000000";
+ ss >> u;
+ BOOST_TEST_EQ(u, u1);
+
+ ss << L"12345678-90ab-cdef-1234-567890abcdef";
+ ss >> u;
+ BOOST_TEST_EQ(u, u3);
+ }
+#endif
+
     { // test with lexical_cast
         BOOST_TEST_EQ(boost::lexical_cast<std::string>(u1), std::string("00000000-0000-0000-0000-000000000000"));
         BOOST_TEST_EQ(boost::lexical_cast<uuid>("00000000-0000-0000-0000-000000000000"), u1);
@@ -59,5 +128,27 @@
         BOOST_TEST_EQ(boost::lexical_cast<uuid>("12345678-90ab-cdef-1234-567890abcdef"), u3);
     }
 
- return boost::report_errors();
+#ifndef BOOST_NO_STD_WSTRING
+ { // test with lexical_cast
+ BOOST_TEST_EQ(boost::lexical_cast<std::wstring>(u1), std::wstring(L"00000000-0000-0000-0000-000000000000"));
+ BOOST_TEST_EQ(boost::lexical_cast<uuid>(L"00000000-0000-0000-0000-000000000000"), u1);
+
+ BOOST_TEST_EQ(boost::lexical_cast<std::wstring>(u3), std::wstring(L"12345678-90ab-cdef-1234-567890abcdef"));
+ BOOST_TEST_EQ(boost::lexical_cast<uuid>(L"12345678-90ab-cdef-1234-567890abcdef"), u3);
+ }
+#endif
+
+ { // test to_string
+ BOOST_TEST_EQ(to_string(u1), std::string("00000000-0000-0000-0000-000000000000"));
+ BOOST_TEST_EQ(to_string(u3), std::string("12345678-90ab-cdef-1234-567890abcdef"));
+ }
+
+#ifndef BOOST_NO_STD_WSTRING
+ { // test to_wstring
+ BOOST_TEST_EQ(to_wstring(u1), std::wstring(L"00000000-0000-0000-0000-000000000000"));
+ BOOST_TEST_EQ(to_wstring(u3), std::wstring(L"12345678-90ab-cdef-1234-567890abcdef"));
+ }
+#endif
+
+ return boost::report_errors();
 }

Modified: branches/release/libs/uuid/uuid.html
==============================================================================
--- branches/release/libs/uuid/uuid.html (original)
+++ branches/release/libs/uuid/uuid.html 2010-07-12 20:37:17 EDT (Mon, 12 Jul 2010)
@@ -60,7 +60,8 @@
         <li>boost/uuid/uuid_io.hpp</li>
         <ul>
             <li>Synopsis</li>
- <li>Input and Output</li>
+ <li>Stream Operators</li>
+ <li>To String</li>
         </ul>
         <li>boost/uuid/uuid_serialize.hpp</li>
         <ul>
@@ -84,7 +85,7 @@
 different databases, or for publication/subscription services. Network messages
 may be identified with a UUID to ensure that different parts of a message are put
 back together again. Distributed computing may use UUIDs to identify a remote
-procedure call. Transactions and classes involved in serialization may be
+procedure call. Transactions and classes involved in serialization may be
 identified by UUIDs. Microsoft's component object model (COM) uses UUIDs to
 distinguish different software component interfaces. UUIDs are inserted into
 documents from Microsoft Office programs. UUIDs identify audio or
@@ -167,6 +168,11 @@
 mechanisms. But a class based on a UUID can be defined
 that does initialize itself to a value generated by one of
 the defined mechanisms.
+<p>
+Note that <tt>boost::is_pod</tt> is specialized for <tt>boost::uuids::uuid</tt>
+and depends on Boost.TypeTraits.
+Define <tt>BOOST_UUID_NO_TYPE_TRAITS</tt> before including boost/uuid/uuid.hpp
+to remove the dependency on Boost.TypeTraits.
 <pre>
 // example using memcpy and aggregate initializers
 // example of a class uuid see boost/libs/uuid/test/test_uuid_class.cpp
@@ -441,10 +447,10 @@
 <p>The <tt>boost::uuids::string_generator</tt> class generates a <b>uuid</b> from a string.
 <pre>
 boost::uuids::string_generator gen;
-boost::uuids::uuid u1 = gen("{01234567-89ab-cdef-0123456789abcdef}");
-boost::uuids::uuid u2 = gen(L"01234567-89ab-cdef-0123456789abcdef");
+boost::uuids::uuid u1 = gen("{01234567-89ab-cdef-0123-456789abcdef}");
+boost::uuids::uuid u2 = gen(L"01234567-89ab-cdef-0123-456789abcdef");
 boost::uuids::uuid u3 = gen(std::string("0123456789abcdef0123456789abcdef"));
-boost::uuids::uuid u4 = gen(std::wstring(L"01234567-89ab-cdef-0123456789abcdef"));
+boost::uuids::uuid u4 = gen(std::wstring(L"01234567-89ab-cdef-0123-456789abcdef"));
 </pre>
 
 <h3><a name="boost/uuid/name_generator.hpp" href="./../../boost/uuid/name_generator.hpp">boost/uuid/name_generator.hpp</a></h3>
@@ -538,22 +544,53 @@
 
 template &lt;typename ch, typename char_traits&gt;
     std::basic_istream&lt;ch, char_traits&gt;&amp; operator&gt;&gt;(std::basic_istream&lt;ch, char_traits&gt; &amp;is, uuid &amp;u);
+
+std::string to_string(uuid const&amp; u);
+std::wstring to_wstring(uuid const&amp; u);
 
 }} // namespace boost::uuids
 </pre>
 
-<h4><a name="Input and Output">Input and Output</a></h4>
+<h4><a name="Stream_operators">Stream Operators</a></h4>
 <p>
-Input and output stream operators <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt>
-are provided by including boost/uuid/uuid_io.hpp.
-The external representation of a <b>uuid</b> is a string of
-hexidecimal digits of the following form: <tt>hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh</tt>
+The standard input and output stream operators <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt>
+are provided by including boost/uuid/uuid_io.hpp.
+The string representation of a <b>uuid</b> is <tt>hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh</tt>
+where <tt>h</tt> is a hexidecimal digit.
 <pre>
-boost::uuids::uuid u;
+boost::uuids::uuid u1; // initialize uuid
 
 std::stringstream ss;
-ss &lt;&lt; u;
-ss &gt;&gt; u;
+ss &lt;&lt; u1;
+
+boost::uuids::uuid u2;
+ss &gt;&gt; u2;
+
+assert(u1, u2);
+</pre>
+
+<p>
+One can also use boost::lexical_cast.
+<pre>
+boost::uuids::uuid u1; // initialize uuid
+
+std::string s = boost::lexical_cast&lt;std::string&gt;(u);
+boost::uuids::uuid u2 = boost::lexical_cast&lt;boost::uuids::uuid&gt;(s);
+
+assert(u1 == u2);
+</pre>
+
+<h4><a name="to_string">To String</a></h4>
+<p>
+The functions <tt>to_string</tt> and <tt>to_wstring</tt> are provided as a
+convenience to convert a <b>uuid</b> to a string. They are also likely faster than
+the stream operators or using boost::lexical_cast.
+<pre>
+boost::uuids::uuid u; // initialize uuid
+
+std::string s1 = to_string(u);
+
+std::wstring s2 = to_wstring(u);
 </pre>
 
 <h3><a name="boost/uuid/uuid_serialize.hpp" href="./../../boost/uuid/uuid_serialize.hpp">boost/uuid/uuid_serialize.hpp</a></h3>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk