Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86385 - in trunk: boost/uuid boost/uuid/detail libs/uuid libs/uuid/test
From: andrey.semashev_at_[hidden]
Date: 2013-10-21 19:01:25


Author: andysem
Date: 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013)
New Revision: 86385
URL: http://svn.boost.org/trac/boost/changeset/86385

Log:
Added optimizations for C++11 and SSE. Refs #8509.

Added:
   trunk/boost/uuid/detail/
   trunk/boost/uuid/detail/config.hpp (contents, props changed)
   trunk/boost/uuid/detail/uuid_generic.hpp (contents, props changed)
   trunk/boost/uuid/detail/uuid_x86.hpp (contents, props changed)
   trunk/libs/uuid/test/test_uuid_no_simd.cpp (contents, props changed)
Text files modified:
   trunk/boost/uuid/detail/config.hpp | 62 ++++++++++++++++++++++
   trunk/boost/uuid/detail/uuid_generic.hpp | 51 ++++++++++++++++++
   trunk/boost/uuid/detail/uuid_x86.hpp | 109 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/uuid/uuid.hpp | 83 +++++++++++++----------------
   trunk/libs/uuid/test/Jamfile.v2 | 1
   trunk/libs/uuid/test/test_uuid.cpp | 7 ++
   trunk/libs/uuid/test/test_uuid_no_simd.cpp | 87 +++++++++++++++++++++++++++++++
   trunk/libs/uuid/uuid.html | 86 +++++++++++++++++++++----------
   8 files changed, 412 insertions(+), 74 deletions(-)

Added: trunk/boost/uuid/detail/config.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/uuid/detail/config.hpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -0,0 +1,62 @@
+/*
+ * Copyright Andrey Semashev 2013.
+ * 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)
+ */
+/*!
+ * \file uuid/detail/config.hpp
+ *
+ * \brief This header defines configuration macros for Boost.UUID.
+ */
+
+#ifndef BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
+#define BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_UUID_NO_SIMD)
+
+#if defined(__GNUC__) && defined(__SSE2__)
+
+// GCC and its pretenders go here
+#ifndef BOOST_UUID_USE_SSE2
+#define BOOST_UUID_USE_SSE2
+#endif
+
+#if defined(__SSE3__) && !defined(BOOST_UUID_USE_SSE3)
+#define BOOST_UUID_USE_SSE3
+#endif
+
+#if defined(__SSE4_1__) && !defined(BOOST_UUID_USE_SSE41)
+#define BOOST_UUID_USE_SSE41
+#endif
+
+#elif defined(_MSC_VER) && (defined(_M_X64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2))
+
+#ifndef BOOST_UUID_USE_SSE2
+#define BOOST_UUID_USE_SSE2
+#endif
+
+#elif !defined(BOOST_UUID_USE_SSE41) && !defined(BOOST_UUID_USE_SSE3) && !defined(BOOST_UUID_USE_SSE2)
+
+#define BOOST_UUID_NO_SIMD
+
+#endif
+
+// More advanced ISA extensions imply less advanced are also available
+#if !defined(BOOST_UUID_USE_SSE3) && defined(BOOST_UUID_USE_SSE41)
+#define BOOST_UUID_USE_SSE3
+#endif
+
+#if !defined(BOOST_UUID_USE_SSE2) && defined(BOOST_UUID_USE_SSE3)
+#define BOOST_UUID_USE_SSE2
+#endif
+
+#endif // !defined(BOOST_UUID_NO_SIMD)
+
+#endif // BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_

Added: trunk/boost/uuid/detail/uuid_generic.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/uuid/detail/uuid_generic.hpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -0,0 +1,51 @@
+/*
+ * Copyright Andy Tompkins 2006.
+ * 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)
+ */
+/*!
+ * \file uuid/detail/uuid_generic.hpp
+ *
+ * \brief This header contains generic implementation of \c boost::uuid operations.
+ */
+
+#ifndef BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
+#define BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
+
+#include <string.h>
+
+namespace boost {
+namespace uuids {
+
+inline bool uuid::is_nil() const BOOST_NOEXCEPT
+{
+ for (std::size_t i = 0; i < sizeof(data); ++i)
+ {
+ if (data[i] != 0U)
+ return false;
+ }
+ return true;
+}
+
+inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
+{
+ uuid tmp = *this;
+ *this = rhs;
+ rhs = tmp;
+}
+
+inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
+{
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0;
+}
+
+inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
+{
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
+}
+
+} // namespace uuids
+} // namespace boost
+
+#endif // BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_

Added: trunk/boost/uuid/detail/uuid_x86.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/uuid/detail/uuid_x86.hpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -0,0 +1,109 @@
+/*
+ * Copyright Andrey Semashev 2013.
+ * 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)
+ */
+/*!
+ * \file uuid/detail/uuid_x86.hpp
+ *
+ * \brief This header contains optimized SSE implementation of \c boost::uuid operations.
+ */
+
+#ifndef BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
+#define BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
+
+// MSVC does not always have immintrin.h (at least, not up to MSVC 10), so include the appropriate header for each instruction set
+#if defined(BOOST_UUID_USE_SSE41)
+#include <smmintrin.h>
+#elif defined(BOOST_UUID_USE_SSE3)
+#include <pmmintrin.h>
+#else
+#include <emmintrin.h>
+#endif
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+BOOST_FORCEINLINE __m128i load_unaligned_si128(const uint8_t* p) BOOST_NOEXCEPT
+{
+#if defined(BOOST_UUID_USE_SSE3)
+ return _mm_lddqu_si128(reinterpret_cast< const __m128i* >(p));
+#else
+ return _mm_loadu_si128(reinterpret_cast< const __m128i* >(p));
+#endif
+}
+
+} // namespace detail
+
+inline bool uuid::is_nil() const BOOST_NOEXCEPT
+{
+ register __m128i mm = uuids::detail::load_unaligned_si128(data);
+#if defined(BOOST_UUID_USE_SSE41)
+ return _mm_test_all_zeros(mm, mm) != 0;
+#else
+ mm = _mm_cmpeq_epi8(mm, _mm_setzero_si128());
+ return _mm_movemask_epi8(mm) == 0xFFFF;
+#endif
+}
+
+inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
+{
+ register __m128i mm_this = uuids::detail::load_unaligned_si128(data);
+ register __m128i mm_rhs = uuids::detail::load_unaligned_si128(rhs.data);
+ _mm_storeu_si128(reinterpret_cast< __m128i* >(rhs.data), mm_this);
+ _mm_storeu_si128(reinterpret_cast< __m128i* >(data), mm_rhs);
+}
+
+inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
+{
+ register __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
+ register __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
+
+ register __m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right);
+#if defined(BOOST_UUID_USE_SSE41)
+ return _mm_test_all_ones(mm_cmp);
+#else
+ return _mm_movemask_epi8(mm_cmp) == 0xFFFF;
+#endif
+}
+
+inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
+{
+ register __m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
+ register __m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
+
+ // To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one.
+ // Then we know which bytes are equivalent and which ones are different, and for those different the comparison results
+ // will be opposite. Then we'll be able to find the first differing comparison result (for both forward and reverse ways),
+ // and depending on which way it is for, this will be the result of the operation. There are a few notes to consider:
+ //
+ // 1. Due to little endian byte order the first bytes go into the lower part of the xmm registers,
+ // so the comparison results in the least significant bits will actually be the most signigicant for the final operation result.
+ // This means we have to determine which of the comparison results have the least significant bit on, and this is achieved with
+ // the "(x - 1) ^ x" trick.
+ // 2. Because there is only signed comparison in SSE/AVX, we have to invert byte comparison results whenever signs of the corresponding
+ // bytes are different. I.e. in signed comparison it's -1 < 1, but in unsigned it is the opposite (255 > 1). To do that we XOR left and right,
+ // making the most significant bit of each byte 1 if the signs are different, and later apply this mask with another XOR to the comparison results.
+ // 3. pcmpgtw compares for "greater" relation, so we swap the arguments to get what we need.
+
+ const __m128i mm_signs_mask = _mm_xor_si128(mm_left, mm_right);
+
+ __m128i mm_cmp = _mm_cmpgt_epi8(mm_right, mm_left), mm_rcmp = _mm_cmpgt_epi8(mm_left, mm_right);
+
+ mm_cmp = _mm_xor_si128(mm_signs_mask, mm_cmp);
+ mm_rcmp = _mm_xor_si128(mm_signs_mask, mm_rcmp);
+
+ uint32_t cmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_cmp)), rcmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_rcmp));
+
+ cmp = (cmp - 1u) ^ cmp;
+ rcmp = (rcmp - 1u) ^ rcmp;
+
+ return static_cast< uint16_t >(cmp) < static_cast< uint16_t >(rcmp);
+}
+
+} // namespace uuids
+} // namespace boost
+
+#endif // BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_

Modified: trunk/boost/uuid/uuid.hpp
==============================================================================
--- trunk/boost/uuid/uuid.hpp Mon Oct 21 18:01:40 2013 (r86384)
+++ trunk/boost/uuid/uuid.hpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -28,20 +28,23 @@
 // 28 Nov 2009 - disabled deprecated warnings for MSVC
 // 30 Nov 2009 - used BOOST_STATIC_CONSTANT
 // 02 Dec 2009 - removed BOOST_STATIC_CONSTANT - not all compilers like it
+// 29 Apr 2013 - added support for noexcept and constexpr, added optimizations for SSE/AVX
 
 #ifndef BOOST_UUID_HPP
 #define BOOST_UUID_HPP
 
-#include <boost/config.hpp>
-#include <stddef.h>
+#include <cstddef>
 #include <boost/cstdint.hpp>
-#include <algorithm>
-#include <boost/config.hpp> // for static assert
+#include <boost/uuid/detail/config.hpp>
 #ifndef BOOST_UUID_NO_TYPE_TRAITS
 #include <boost/type_traits/is_pod.hpp>
 #include <boost/type_traits/integral_constant.hpp>
 #endif
 
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
 #if defined(_MSC_VER)
 #pragma warning(push) // Save warning settings.
 #pragma warning(disable : 4996) // Disable deprecated std::swap_ranges, std::equal
@@ -69,28 +72,20 @@
     typedef std::ptrdiff_t difference_type;
 
     // This does not work on some compilers
- // They seem to want the variable definec in
+ // They seem to want the variable definec in
     // a cpp file
     //BOOST_STATIC_CONSTANT(size_type, static_size = 16);
- static size_type static_size() { return 16; }
+ static BOOST_CONSTEXPR size_type static_size() BOOST_NOEXCEPT { return 16; }
 
 public:
- iterator begin() { return data; } /* throw() */
- const_iterator begin() const { return data; } /* throw() */
- iterator end() { return data+size(); } /* throw() */
- const_iterator end() const { return data+size(); } /* throw() */
+ iterator begin() BOOST_NOEXCEPT { return data; }
+ const_iterator begin() const BOOST_NOEXCEPT { return data; }
+ iterator end() BOOST_NOEXCEPT { return data+size(); }
+ const_iterator end() const BOOST_NOEXCEPT { return data+size(); }
 
- size_type size() const { return static_size(); } /* throw() */
+ BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return static_size(); }
 
- bool is_nil() const /* throw() */
- {
- for(size_t i=0; i<static_size(); i++) {
- if (data[i] != 0U) {
- return false;
- }
- }
- return true;
- }
+ bool is_nil() const BOOST_NOEXCEPT;
 
     enum variant_type
     {
@@ -99,7 +94,7 @@
         variant_microsoft, // Microsoft Corporation backward compatibility
         variant_future // future definition
     };
- variant_type variant() const /* throw() */
+ variant_type variant() const BOOST_NOEXCEPT
     {
         // variant is stored in octet 7
         // which is index 8, since indexes count backwards
@@ -115,8 +110,8 @@
             return variant_future;
         }
     }
-
- enum version_type
+
+ enum version_type
     {
         version_unknown = -1,
         version_time_based = 1,
@@ -125,11 +120,11 @@
         version_random_number_based = 4,
         version_name_based_sha1 = 5
     };
- version_type version() const /* throw() */
+ version_type version() const BOOST_NOEXCEPT
     {
- //version is stored in octet 9
+ // version is stored in octet 9
         // which is index 6, since indexes count backwards
- unsigned char octet9 = data[6];
+ uint8_t octet9 = data[6];
         if ( (octet9 & 0xF0) == 0x10 ) {
             return version_time_based;
         } else if ( (octet9 & 0xF0) == 0x20 ) {
@@ -146,55 +141,45 @@
     }
 
     // note: linear complexity
- void swap(uuid& rhs) /* throw() */
- {
- std::swap_ranges(begin(), end(), rhs.begin());
- }
+ void swap(uuid& rhs) BOOST_NOEXCEPT;
 
 public:
     // or should it be array<uint8_t, 16>
     uint8_t data[16];
 };
 
-inline bool operator==(uuid const& lhs, uuid const& rhs) /* throw() */
-{
- return std::equal(lhs.begin(), lhs.end(), rhs.begin());
-}
+bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
+bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
 
-inline bool operator!=(uuid const& lhs, uuid const& rhs) /* throw() */
+inline bool operator!=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
 {
     return !(lhs == rhs);
 }
 
-inline bool operator<(uuid const& lhs, uuid const& rhs) /* throw() */
-{
- return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
-}
-
-inline bool operator>(uuid const& lhs, uuid const& rhs) /* throw() */
+inline bool operator>(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
 {
     return rhs < lhs;
 }
-inline bool operator<=(uuid const& lhs, uuid const& rhs) /* throw() */
+inline bool operator<=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
 {
     return !(rhs < lhs);
 }
 
-inline bool operator>=(uuid const& lhs, uuid const& rhs) /* throw() */
+inline bool operator>=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
 {
     return !(lhs < rhs);
 }
 
-inline void swap(uuid& lhs, uuid& rhs) /* throw() */
+inline void swap(uuid& lhs, uuid& rhs) BOOST_NOEXCEPT
 {
     lhs.swap(rhs);
 }
 
 // This is equivalent to boost::hash_range(u.begin(), u.end());
-inline std::size_t hash_value(uuid const& u) /* throw() */
+inline std::size_t hash_value(uuid const& u) BOOST_NOEXCEPT
 {
     std::size_t seed = 0;
- for(uuid::const_iterator i=u.begin(); i != u.end(); ++i)
+ for(uuid::const_iterator i=u.begin(), e=u.end(); i != e; ++i)
     {
         seed ^= static_cast<std::size_t>(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
     }
@@ -214,6 +199,12 @@
 } // namespace boost
 #endif
 
+#if defined(BOOST_UUID_USE_SSE2)
+#include <boost/uuid/detail/uuid_x86.hpp>
+#else
+#include <boost/uuid/detail/uuid_generic.hpp>
+#endif
+
 #if defined(_MSC_VER)
 #pragma warning(pop) // Restore warnings to previous state.
 #endif

Modified: trunk/libs/uuid/test/Jamfile.v2
==============================================================================
--- trunk/libs/uuid/test/Jamfile.v2 Mon Oct 21 18:01:40 2013 (r86384)
+++ trunk/libs/uuid/test/Jamfile.v2 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -25,6 +25,7 @@
 
     # main test
     [ run test_uuid.cpp ]
+ [ run test_uuid_no_simd.cpp ]
 
     # test uuid_io.hpp
     [ run test_io.cpp ]

Modified: trunk/libs/uuid/test/test_uuid.cpp
==============================================================================
--- trunk/libs/uuid/test/test_uuid.cpp Mon Oct 21 18:01:40 2013 (r86384)
+++ trunk/libs/uuid/test/test_uuid.cpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -156,6 +156,8 @@
         uuid u1 = {{0}};
         uuid u2 = {{1,0}};
         uuid u3 = {{255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}};
+ uuid u4 = {{0,1,0}};
+ uuid u5 = {{0,255,0}};
 
         BOOST_TEST_EQ(u1, u1);
 
@@ -163,6 +165,11 @@
    
         BOOST_TEST(u1 < u2);
         BOOST_TEST(u2 < u3);
+ BOOST_TEST(u1 < u4);
+ BOOST_TEST(u1 < u5);
+ BOOST_TEST(u4 < u5);
+ BOOST_TEST(u4 < u2);
+ BOOST_TEST(u5 < u2);
 
         BOOST_TEST(u1 <= u1);
         BOOST_TEST(u1 <= u2);

Added: trunk/libs/uuid/test/test_uuid_no_simd.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/uuid/test/test_uuid_no_simd.cpp 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -0,0 +1,87 @@
+// (C) Copyright Andy Tompkins 2007. Permission to copy, use, modify, sell and
+// distribute this software is granted provided this copyright notice appears
+// in all copies. This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+// 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)
+
+// libs/uuid/test/test_uuid_no_simd.cpp -------------------------------//
+
+// This test is a subset of libs/uuid/test/test_uuid.cpp, compiled without any
+// SIMD optimizations. The test specifically verifies generic implementations
+// of the routines.
+
+#define BOOST_UUID_NO_SIMD
+
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main(int, char*[])
+{
+ using namespace boost::uuids;
+
+ { // uuid::operator=()
+ uuid u1 = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
+ uuid u2 = u1;
+ BOOST_TEST_EQ(u2, u1);
+ }
+
+ { // uuid::is_nil()
+ uuid u1 = {{0}};
+ BOOST_TEST_EQ(u1.is_nil(), true);
+
+ uuid u2 = {{1,0}};
+ BOOST_TEST_EQ(u2.is_nil(), false);
+ }
+
+ { // uuid::swap(), swap()
+ uuid u1 = {{0}};
+ uuid u2 = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
+ u1.swap(u2);
+
+ unsigned char values1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ unsigned char values2[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+ BOOST_TEST_UUID(u1, values2);
+ BOOST_TEST_UUID(u2, values1);
+
+ swap(u1, u2);
+ BOOST_TEST_UUID(u1, values1);
+ BOOST_TEST_UUID(u2, values2);
+ }
+
+ { // test comparsion
+ uuid u1 = {{0}};
+ uuid u2 = {{1,0}};
+ uuid u3 = {{255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}};
+ uuid u4 = {{0,1,0}};
+ uuid u5 = {{0,255,0}};
+
+ BOOST_TEST_EQ(u1, u1);
+
+ BOOST_TEST_NE(u1, u2);
+
+ BOOST_TEST(u1 < u2);
+ BOOST_TEST(u2 < u3);
+ BOOST_TEST(u1 < u4);
+ BOOST_TEST(u1 < u5);
+ BOOST_TEST(u4 < u5);
+ BOOST_TEST(u4 < u2);
+ BOOST_TEST(u5 < u2);
+
+ BOOST_TEST(u1 <= u1);
+ BOOST_TEST(u1 <= u2);
+ BOOST_TEST(u2 <= u3);
+
+ BOOST_TEST(u2 >= u1);
+ BOOST_TEST(u3 >= u1);
+
+ BOOST_TEST(u3 >= u3);
+ BOOST_TEST(u2 >= u1);
+ BOOST_TEST(u3 >= u1);
+ }
+
+ return boost::report_errors();
+}

Modified: trunk/libs/uuid/uuid.html
==============================================================================
--- trunk/libs/uuid/uuid.html Mon Oct 21 18:01:40 2013 (r86384)
+++ trunk/libs/uuid/uuid.html 2013-10-21 19:01:25 EDT (Mon, 21 Oct 2013) (r86385)
@@ -13,6 +13,7 @@
 
 <ol>
     <li>Introduction</li>
+ <li>Configuration</li>
     <li>Examples</li>
     <ul>
         <li>Tagging</li>
@@ -103,6 +104,35 @@
 never be generated again), or it is extremely likely to be unique (depending
 on the mechanism).
 
+<h2><a name="Configuration">Configuration</a></h2>
+
+<p>
+The library does not require building or any special configuration to be used.
+However, there are a few options that can be enabled by defining macros prior to
+including library headers. These macros are summarized in the following table.
+
+<p>
+<table border="1">
+<tr>
+<th>Macro</th><th>Description</th>
+</tr>
+<tr>
+<td><tt>BOOST_UUID_NO_SIMD</tt></td><td>If defined, disables any optimizations for SIMD-enabled processors. Generic versions of algorithms will be used instead. This may result in suboptimal performance. By default, optimized algorithms are used, when the library is able to detect the availability of SIMD extensions at compile time.</td>
+</tr>
+<tr>
+<td><tt>BOOST_UUID_USE_SSE2</tt></td><td>If defined, enables optimizations for SSE2 exstensions available in modern x86 processors.</td>
+</tr>
+<tr>
+<td><tt>BOOST_UUID_USE_SSE3</tt></td><td>If defined, enables optimizations for SSE3 exstensions available in modern x86 processors.</td>
+</tr>
+<tr>
+<td><tt>BOOST_UUID_USE_SSE41</tt></td><td>If defined, enables optimizations for SSE4.1 exstensions available in modern x86 processors.</td>
+</tr>
+</table>
+
+<p>
+By default the library attempts to detect the availability of SIMD extensions in the target CPU at compile time and automatically defines the appropriate macros if succeeded. The <tt>BOOST_UUID_USE_SSE*</tt> macros can be defined by users, if auto-detection fails and it is known that the target CPU will have the extension. Do not enable these extensions unless you're certain that they will always be available on any machine that will run your program. The library performs no run time checks, so if an extension is missing, the program will likely crash. Note that enabling more advanced extensions implies that more basic ones are also available.
+
 <h2><a name="Examples">Examples</a></h2>
 <h3><a name="Tagging">Tagging</a></h3>
 <pre>
@@ -119,32 +149,32 @@
         : tag(boost::uuids::random_generator()())
         , state(0)
     {}
-
+
     explicit object(int state)
         : tag(boost::uuids::random_generator()())
         , state(state)
     {}
-
+
     object(object const&amp; rhs)
         : tag(rhs.tag)
         , state(rhs.state)
     {}
-
+
     bool operator==(object const&amp; rhs) const {
         return tag == rhs.tag;
     }
-
+
     object&amp; operator=(object const&amp; rhs) {
         tag = rhs.tag;
         state = rhs.state;
     }
-
+
     int get_state() const { return state; }
     void set_state(int new_state) { state = new_state; }
-
+
 private:
     boost::uuids::uuid tag;
-
+
     int state;
 };
 
@@ -209,7 +239,7 @@
     uuid_class()
         : boost::uuids::uuid(boost::uuids::random_generator()())
     {}
-
+
     explicit uuid_class(boost::uuids::uuid const&amp; u)
         : boost::uuids::uuid(u)
     {}
@@ -258,25 +288,25 @@
     typedef std::size_t size_type;
     typedef std::ptrdiff_t difference_type;
 
- static size_type static_size();
+ static constexpr size_type static_size() noexcept;
 
     // iteration
- iterator begin();
- iterator end();
- const_iterator begin() const;
- const_iterator end() const;
+ iterator begin() noexcept;
+ iterator end() noexcept;
+ const_iterator begin() const noexcept;
+ const_iterator end() const noexcept;
 
- size_type size() const;
+ constexpr size_type size() const noexcept;
+
+ bool is_nil() const noexcept;
 
- bool is_nil() const;
-
     enum variant_type {
         variant_ncs, // NCS backward compatibility
         variant_rfc_4122, // defined in RFC 4122 document
         variant_microsoft, // Microsoft Corporation backward compatibility
         variant_future // future definition
     };
- variant_type variant() const;
+ variant_type variant() const noexcept;
 
     enum version_type {
         version_unknown = -1,
@@ -286,25 +316,25 @@
         version_random_number_based = 4,
         version_name_based_sha1 = 5
     };
- version_type version() const;
+ version_type version() const noexcept;
 
     // Swap function
- void swap(uuid&amp; rhs);
+ void swap(uuid&amp; rhs) noexcept;
 
     uint8_t data[static_size()];
 };
 
 // standard operators
-bool operator==(uuid const&amp; lhs, uuid const&amp; rhs);
-bool operator!=(uuid const&amp; lhs, uuid const&amp; rhs);
-bool operator&lt;(uuid const&amp; lhs, uuid const&amp; rhs);
-bool operator&gt;(uuid const&amp; lhs, uuid const&amp; rhs);
-bool operator&lt;=(uuid const&amp; lhs, uuid const&amp; rhs);
-bool operator&gt;=(uuid const&amp; lhs, uuid const&amp; rhs);
+bool operator==(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
+bool operator!=(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
+bool operator&lt;(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
+bool operator&gt;(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
+bool operator&lt;=(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
+bool operator&gt;=(uuid const&amp; lhs, uuid const&amp; rhs) noexcept;
 
-void swap(uuid&amp; lhs, uuid&amp; rhs);
+void swap(uuid&amp; lhs, uuid&amp; rhs) noexcept;
 
-std::size_t hash_value(uuid const&amp; u);
+std::size_t hash_value(uuid const&amp; u) noexcept;
 
 }} // namespace boost::uuids
 </pre>
@@ -335,7 +365,7 @@
 </pre>
 
 <h4><a name="Nil">Nil uuid</a></h4>
-<p>The function, <tt>boost::uuids::uuid::is_null()</tt> returns true if and
+<p>The function, <tt>boost::uuids::uuid::is_nil()</tt> returns true if and
 only if the <b>uuid</b> is equal to {00000000-0000-0000-0000-000000000000}.
 </p>
 


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