diff --git a/cpp/BoostParts/boost/algorithm/string/concept.hpp b/cpp/BoostParts/boost/algorithm/string/concept.hpp index 9876e98d..17e83495 100644 --- a/cpp/BoostParts/boost/algorithm/string/concept.hpp +++ b/cpp/BoostParts/boost/algorithm/string/concept.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_CONCEPT_HPP #include -#include +#include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/find_format.hpp b/cpp/BoostParts/boost/algorithm/string/detail/find_format.hpp index 1612b937..b3987502 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/find_format.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/find_format.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_FIND_FORMAT_DETAIL_HPP #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/find_format_all.hpp b/cpp/BoostParts/boost/algorithm/string/detail/find_format_all.hpp index 51ad5667..52930c83 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/find_format_all.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/find_format_all.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/find_format_store.hpp b/cpp/BoostParts/boost/algorithm/string/detail/find_format_store.hpp index e8bd84a6..b9f4a88d 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/find_format_store.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/find_format_store.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP #include -#include +#include namespace boost { namespace algorithm { diff --git a/cpp/BoostParts/boost/algorithm/string/detail/find_iterator.hpp b/cpp/BoostParts/boost/algorithm/string/detail/find_iterator.hpp index c76993a1..9b78a0f7 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/find_iterator.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/find_iterator.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/finder.hpp b/cpp/BoostParts/boost/algorithm/string/detail/finder.hpp index 93310d05..209ce0b2 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/finder.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/finder.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -142,7 +142,6 @@ namespace boost { ForwardIteratorT End, std::forward_iterator_tag ) const { - typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; first_finder_type first_finder( @@ -263,7 +262,6 @@ namespace boost { ForwardIteratorT End, unsigned int N) const { - typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; // Sanity check @@ -298,7 +296,6 @@ namespace boost { ForwardIteratorT End, unsigned int N) const { - typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; // Sanity check @@ -362,7 +359,6 @@ namespace boost { unsigned int N, std::random_access_iterator_tag ) { - typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) @@ -436,7 +432,6 @@ namespace boost { unsigned int N, std::random_access_iterator_tag ) { - typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) diff --git a/cpp/BoostParts/boost/algorithm/string/detail/finder_regex.hpp b/cpp/BoostParts/boost/algorithm/string/detail/finder_regex.hpp index 01bf5a08..9cb01cfa 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/finder_regex.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/finder_regex.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/formatter.hpp b/cpp/BoostParts/boost/algorithm/string/detail/formatter.hpp index 8e7b727e..c071822f 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/formatter.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/formatter.hpp @@ -12,7 +12,7 @@ #define BOOST_STRING_FORMATTER_DETAIL_HPP -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/detail/util.hpp b/cpp/BoostParts/boost/algorithm/string/detail/util.hpp index 7e8471f7..cf4a8b1c 100644 --- a/cpp/BoostParts/boost/algorithm/string/detail/util.hpp +++ b/cpp/BoostParts/boost/algorithm/string/detail/util.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace boost { namespace algorithm { diff --git a/cpp/BoostParts/boost/algorithm/string/erase.hpp b/cpp/BoostParts/boost/algorithm/string/erase.hpp index e738b86f..68837909 100644 --- a/cpp/BoostParts/boost/algorithm/string/erase.hpp +++ b/cpp/BoostParts/boost/algorithm/string/erase.hpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/find.hpp b/cpp/BoostParts/boost/algorithm/string/find.hpp index da1cb616..f2c2926b 100644 --- a/cpp/BoostParts/boost/algorithm/string/find.hpp +++ b/cpp/BoostParts/boost/algorithm/string/find.hpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/find_format.hpp b/cpp/BoostParts/boost/algorithm/string/find_format.hpp index ef037391..0e84a4ee 100644 --- a/cpp/BoostParts/boost/algorithm/string/find_format.hpp +++ b/cpp/BoostParts/boost/algorithm/string/find_format.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/find_iterator.hpp b/cpp/BoostParts/boost/algorithm/string/find_iterator.hpp index e8cede5e..1502c7d9 100644 --- a/cpp/BoostParts/boost/algorithm/string/find_iterator.hpp +++ b/cpp/BoostParts/boost/algorithm/string/find_iterator.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -132,12 +132,7 @@ namespace boost { // increment void increment() { - if(m_Match.begin() == m_Match.end()) - m_Match=this->do_find(m_Match.end(),m_End); - else { - input_iterator_type last = m_Match.begin(); - m_Match=this->do_find(++last,m_End); - } + m_Match=this->do_find(m_Match.end(),m_End); } // comparison diff --git a/cpp/BoostParts/boost/algorithm/string/finder.hpp b/cpp/BoostParts/boost/algorithm/string/finder.hpp index 4c7ac38b..93f7ec30 100644 --- a/cpp/BoostParts/boost/algorithm/string/finder.hpp +++ b/cpp/BoostParts/boost/algorithm/string/finder.hpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/formatter.hpp b/cpp/BoostParts/boost/algorithm/string/formatter.hpp index c2c13eb2..de8681bc 100644 --- a/cpp/BoostParts/boost/algorithm/string/formatter.hpp +++ b/cpp/BoostParts/boost/algorithm/string/formatter.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/iter_find.hpp b/cpp/BoostParts/boost/algorithm/string/iter_find.hpp index e1065283..10424abc 100644 --- a/cpp/BoostParts/boost/algorithm/string/iter_find.hpp +++ b/cpp/BoostParts/boost/algorithm/string/iter_find.hpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/predicate.hpp b/cpp/BoostParts/boost/algorithm/string/predicate.hpp index 6642f427..0879829b 100644 --- a/cpp/BoostParts/boost/algorithm/string/predicate.hpp +++ b/cpp/BoostParts/boost/algorithm/string/predicate.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/regex.hpp b/cpp/BoostParts/boost/algorithm/string/regex.hpp index 0a4c38bd..a6c7c60a 100644 --- a/cpp/BoostParts/boost/algorithm/string/regex.hpp +++ b/cpp/BoostParts/boost/algorithm/string/regex.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/replace.hpp b/cpp/BoostParts/boost/algorithm/string/replace.hpp index f2d201f9..0c04e47e 100644 --- a/cpp/BoostParts/boost/algorithm/string/replace.hpp +++ b/cpp/BoostParts/boost/algorithm/string/replace.hpp @@ -13,7 +13,7 @@ #include -#include +#include #include #include #include diff --git a/cpp/BoostParts/boost/algorithm/string/trim.hpp b/cpp/BoostParts/boost/algorithm/string/trim.hpp index be57cd92..e740d57d 100644 --- a/cpp/BoostParts/boost/algorithm/string/trim.hpp +++ b/cpp/BoostParts/boost/algorithm/string/trim.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/cpp/BoostParts/boost/assert.hpp b/cpp/BoostParts/boost/assert.hpp index a2335058..ccc776a4 100644 --- a/cpp/BoostParts/boost/assert.hpp +++ b/cpp/BoostParts/boost/assert.hpp @@ -34,6 +34,7 @@ #elif defined(BOOST_ENABLE_ASSERT_HANDLER) +#include #include namespace boost @@ -42,7 +43,7 @@ namespace boost char const * function, char const * file, long line); // user defined } // namespace boost -#define BOOST_ASSERT(expr) ((expr) \ +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) @@ -63,6 +64,7 @@ namespace boost #elif defined(BOOST_ENABLE_ASSERT_HANDLER) + #include #include namespace boost @@ -71,7 +73,7 @@ namespace boost char const * function, char const * file, long line); // user defined } // namespace boost - #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) @@ -80,6 +82,7 @@ namespace boost #define BOOST_ASSERT_HPP #include #include + #include #include // IDE's like Visual Studio perform better if output goes to std::cout or @@ -89,31 +92,33 @@ namespace boost #endif namespace boost - { - namespace assertion - { + { + namespace assertion + { namespace detail { - inline void assertion_failed_msg(char const * expr, char const * msg, char const * function, + // Note: The template is needed to make the function non-inline and avoid linking errors + template< typename CharT > + BOOST_NOINLINE void assertion_failed_msg(CharT const * expr, char const * msg, char const * function, char const * file, long line) { BOOST_ASSERT_MSG_OSTREAM << "***** Internal Program Error - assertion (" << expr << ") failed in " << function << ":\n" << file << '(' << line << "): " << msg << std::endl; - #ifdef UNDER_CE - // The Windows CE CRT library does not have abort() so use exit(-1) instead. - std::exit(-1); - #else - std::abort(); - #endif +#ifdef UNDER_CE + // The Windows CE CRT library does not have abort() so use exit(-1) instead. + std::exit(-1); +#else + std::abort(); +#endif } } // detail } // assertion } // detail #endif - #define BOOST_ASSERT_MSG(expr, msg) ((expr) \ + #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ ? ((void)0) \ : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) diff --git a/cpp/BoostParts/boost/atomic.hpp b/cpp/BoostParts/boost/atomic.hpp index 0f5883c3..cc28b1ab 100644 --- a/cpp/BoostParts/boost/atomic.hpp +++ b/cpp/BoostParts/boost/atomic.hpp @@ -11,7 +11,7 @@ #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/cpp/BoostParts/boost/atomic/atomic.hpp b/cpp/BoostParts/boost/atomic/atomic.hpp index 9e1ecbd8..dd3c0146 100644 --- a/cpp/BoostParts/boost/atomic/atomic.hpp +++ b/cpp/BoostParts/boost/atomic/atomic.hpp @@ -22,7 +22,7 @@ #include #endif -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -60,6 +60,10 @@ namespace boost { #define BOOST_ATOMIC_LLONG_LOCK_FREE 0 #endif +#ifndef BOOST_ATOMIC_INT128_LOCK_FREE +#define BOOST_ATOMIC_INT128_LOCK_FREE 0 +#endif + #ifndef BOOST_ATOMIC_POINTER_LOCK_FREE #define BOOST_ATOMIC_POINTER_LOCK_FREE 0 #endif @@ -112,11 +116,18 @@ private: mpl::and_< boost::is_integral, boost::is_signed >::value #endif > super; -public: - atomic(void) BOOST_NOEXCEPT : super() {} - BOOST_CONSTEXPR atomic(value_type v) BOOST_NOEXCEPT : super(v) {} + typedef typename super::value_arg_type value_arg_type; - value_type operator=(value_type v) volatile BOOST_NOEXCEPT +public: + BOOST_DEFAULTED_FUNCTION(atomic(void), BOOST_NOEXCEPT {}) + + // NOTE: The constructor is made explicit because gcc 4.7 complains that + // operator=(value_arg_type) is considered ambiguous with operator=(atomic const&) + // in assignment expressions, even though conversion to atomic<> is less preferred + // than conversion to value_arg_type. + explicit BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : super(v) {} + + value_type operator=(value_arg_type v) volatile BOOST_NOEXCEPT { this->store(v); return v; @@ -127,14 +138,8 @@ public: return this->load(); } -#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS -private: - atomic(const atomic &) /* =delete */ ; - atomic & operator=(const atomic &) volatile /* =delete */ ; -#else - atomic(const atomic &) = delete; - atomic & operator=(const atomic &) volatile = delete; -#endif + BOOST_DELETED_FUNCTION(atomic(atomic const&)) + BOOST_DELETED_FUNCTION(atomic& operator=(atomic const&) volatile) }; typedef atomic atomic_char; @@ -190,25 +195,9 @@ typedef atomic atomic_uintmax_t; typedef atomic atomic_size_t; typedef atomic atomic_ptrdiff_t; -// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config. -#if !defined(__PGIC__) - -#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ - || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ - || defined(__CYGWIN__) \ - || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ - || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined(BOOST_HAS_INTPTR_T) typedef atomic atomic_intptr_t; typedef atomic atomic_uintptr_t; -#elif defined(__GNUC__) || defined(__clang__) -#if defined(__INTPTR_TYPE__) -typedef atomic< __INTPTR_TYPE__ > atomic_intptr_t; -#endif -#if defined(__UINTPTR_TYPE__) -typedef atomic< __UINTPTR_TYPE__ > atomic_uintptr_t; -#endif -#endif - #endif #ifndef BOOST_ATOMIC_FLAG_LOCK_FREE @@ -229,9 +218,11 @@ public: { v_.store(false, order); } + + BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&)) + BOOST_DELETED_FUNCTION(atomic_flag& operator=(atomic_flag const&)) + private: - atomic_flag(const atomic_flag &) /* = delete */ ; - atomic_flag & operator=(const atomic_flag &) /* = delete */ ; atomic v_; }; #endif diff --git a/cpp/BoostParts/boost/atomic/detail/base.hpp b/cpp/BoostParts/boost/atomic/detail/base.hpp index 54dac604..eb105b9b 100644 --- a/cpp/BoostParts/boost/atomic/detail/base.hpp +++ b/cpp/BoostParts/boost/atomic/detail/base.hpp @@ -19,7 +19,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -155,13 +155,14 @@ namespace detail { inline memory_order calculate_failure_order(memory_order order) { - switch(order) { - case memory_order_acq_rel: - return memory_order_acquire; - case memory_order_release: - return memory_order_relaxed; - default: - return order; + switch(order) + { + case memory_order_acq_rel: + return memory_order_acquire; + case memory_order_release: + return memory_order_relaxed; + default: + return order; } } @@ -172,11 +173,12 @@ private: typedef base_atomic this_type; typedef T value_type; typedef lockpool::scoped_lock guard_type; - typedef char storage_type[sizeof(value_type)]; + +protected: + typedef value_type const& value_arg_type; public: - base_atomic(void) {} - + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v) {} @@ -249,15 +251,16 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: char * storage_ptr() volatile const BOOST_NOEXCEPT { return const_cast(&reinterpret_cast(v_)); } - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - T v_; }; @@ -269,9 +272,13 @@ private: typedef T value_type; typedef T difference_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -381,9 +388,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -393,11 +402,15 @@ class base_atomic private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -474,9 +487,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -485,12 +500,16 @@ class base_atomic { private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -572,9 +591,10 @@ public: BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; diff --git a/cpp/BoostParts/boost/atomic/detail/cas128strong.hpp b/cpp/BoostParts/boost/atomic/detail/cas128strong.hpp new file mode 100644 index 00000000..906c13e8 --- /dev/null +++ b/cpp/BoostParts/boost/atomic/detail/cas128strong.hpp @@ -0,0 +1,286 @@ +#ifndef BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP +#define BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP + +// 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) +// +// Copyright (c) 2011 Helge Bahmann +// Copyright (c) 2013 Tim Blechmann, Andrey Semashev + +// Build 128-bit atomic operation on integers/UDTs from platform_cmpxchg128_strong +// primitive. It is assumed that 128-bit loads/stores are not +// atomic, so they are implemented through platform_load128/platform_store128. + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/* integral types */ + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before_store(order); + platform_store128(v, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v = platform_load128(&v_); + platform_fence_after_load(order); + return v; + } + + value_type + exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + compare_exchange_strong( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + platform_fence_before(success_order); + + bool success = platform_cmpxchg128_strong(expected, desired, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + } + + return success; + } + + value_type + fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); + return original; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +/* generic types */ + +#if defined(BOOST_HAS_INT128) + +typedef boost::uint128_type storage128_type; + +#else // defined(BOOST_HAS_INT128) + +struct BOOST_ALIGNMENT(16) storage128_type +{ + uint64_t data[2]; +}; + +inline bool operator== (storage128_type const& left, storage128_type const& right) +{ + return left.data[0] == right.data[0] && left.data[1] == right.data[1]; +} +inline bool operator!= (storage128_type const& left, storage128_type const& right) +{ + return !(left == right); +} + +#endif // defined(BOOST_HAS_INT128) + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef storage128_type storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void + store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type value_s = 0; + memcpy(&value_s, &value, sizeof(value_type)); + platform_fence_before_store(order); + platform_store128(value_s, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type value_s = platform_load128(&v_); + platform_fence_after_load(order); + value_type value; + memcpy(&value, &value_s, sizeof(value_type)); + return value; + } + + value_type + exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + compare_exchange_strong( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + + platform_fence_before(success_order); + bool success = platform_cmpxchg128_strong(expected_s, desired_s, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + memcpy(&expected, &expected_s, sizeof(value_type)); + } + + return success; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +} +} +} + +#endif diff --git a/cpp/BoostParts/boost/atomic/detail/cas32strong.hpp b/cpp/BoostParts/boost/atomic/detail/cas32strong.hpp index ac66a129..27e79839 100644 --- a/cpp/BoostParts/boost/atomic/detail/cas32strong.hpp +++ b/cpp/BoostParts/boost/atomic/detail/cas32strong.hpp @@ -12,13 +12,14 @@ // Build 8-, 16- and 32-bit atomic operations from // a platform_cmpxchg32_strong primitive. +#include #include #include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -31,13 +32,18 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -150,22 +156,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -278,21 +291,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -401,9 +421,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -412,12 +434,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef void * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -499,21 +526,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -595,9 +629,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -606,17 +642,21 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT { @@ -688,26 +728,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT { @@ -780,26 +826,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -872,9 +924,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; diff --git a/cpp/BoostParts/boost/atomic/detail/cas32weak.hpp b/cpp/BoostParts/boost/atomic/detail/cas32weak.hpp index de2314c7..d75215d8 100644 --- a/cpp/BoostParts/boost/atomic/detail/cas32weak.hpp +++ b/cpp/BoostParts/boost/atomic/detail/cas32weak.hpp @@ -9,13 +9,14 @@ // Copyright (c) 2013 Tim Blechmann +#include #include #include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -28,13 +29,18 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -92,11 +98,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -155,22 +163,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -228,11 +243,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -291,21 +308,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -359,11 +383,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -422,9 +448,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -433,12 +461,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef void * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -492,11 +525,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -528,21 +563,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -596,11 +638,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -632,9 +676,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -643,17 +689,21 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -716,11 +766,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -734,26 +786,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -816,11 +874,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -834,26 +894,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -916,11 +982,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -934,9 +1002,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; diff --git a/cpp/BoostParts/boost/atomic/detail/cas64strong-ptr.hpp b/cpp/BoostParts/boost/atomic/detail/cas64strong-ptr.hpp new file mode 100644 index 00000000..2f04112a --- /dev/null +++ b/cpp/BoostParts/boost/atomic/detail/cas64strong-ptr.hpp @@ -0,0 +1,247 @@ +#ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP +#define BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP + +// 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) +// +// Copyright (c) 2011 Helge Bahmann +// Copyright (c) 2013 Tim Blechmann + +// Build 64-bit atomic operation on pointers from platform_cmpxchg64_strong +// primitive. It is assumed that 64-bit loads/stores are not +// atomic, so they are implemented through platform_load64/platform_store64. +// +// The reason for extracting pointer specializations to a separate header is +// that 64-bit CAS is available on some 32-bit platforms (notably, x86). +// On these platforms there is no need for 64-bit pointer specializations, +// since they will never be used. + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/* pointer types */ + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef void * value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before_store(order); + platform_store64(v, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v = platform_load64(&v_); + platform_fence_after_load(order); + return v; + } + + value_type + exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + compare_exchange_strong( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + platform_fence_before(success_order); + + bool success = platform_cmpxchg64_strong(expected, desired, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + } + + return success; + } + + value_type + fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed)); + return original; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T * value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before_store(order); + platform_store64(v, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v = platform_load64(&v_); + platform_fence_after_load(order); + return v; + } + + value_type + exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + compare_exchange_strong( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + platform_fence_before(success_order); + + bool success = platform_cmpxchg64_strong(expected, desired, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + } + + return success; + } + + value_type + fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); + return original; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +} +} +} + +#endif diff --git a/cpp/BoostParts/boost/atomic/detail/cas64strong.hpp b/cpp/BoostParts/boost/atomic/detail/cas64strong.hpp index 0a5002b3..c283f986 100644 --- a/cpp/BoostParts/boost/atomic/detail/cas64strong.hpp +++ b/cpp/BoostParts/boost/atomic/detail/cas64strong.hpp @@ -8,17 +8,18 @@ // Copyright (c) 2011 Helge Bahmann // Copyright (c) 2013 Tim Blechmann -// Build 64-bit atomic operation from platform_cmpxchg64_strong +// Build 64-bit atomic operation on integers/UDTs from platform_cmpxchg64_strong // primitive. It is assumed that 64-bit loads/stores are not -// atomic, so they are funnelled through cmpxchg as well. +// atomic, so they are implemented through platform_load64/platform_store64. +#include #include #include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -31,12 +32,17 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -145,203 +151,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - value_type v_; -}; - -/* pointer types */ - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef void * value_type; - typedef ptrdiff_t difference_type; -public: - BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} - - void - store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - platform_fence_before_store(order); - platform_store64(v, &v_); - platform_fence_after_store(order); - } - - value_type - load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT - { - value_type v = platform_load64(&v_); - platform_fence_after_load(order); - return v; - } - - value_type - exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); - return original; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - compare_exchange_strong( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - platform_fence_before(success_order); - - bool success = platform_cmpxchg64_strong(expected, desired, &v_); - - if (success) { - platform_fence_after(success_order); - } else { - platform_fence_after(failure_order); - } - - return success; - } - - value_type - fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed)); - return original; - } - - value_type - fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed)); - return original; - } - - bool - is_lock_free(void) const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - value_type v_; -}; - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef T * value_type; - typedef ptrdiff_t difference_type; -public: - BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} - - void - store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - platform_fence_before_store(order); - platform_store64(v, &v_); - platform_fence_after_store(order); - } - - value_type - load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT - { - value_type v = platform_load64(&v_); - platform_fence_after_load(order); - return v; - } - - value_type - exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); - return original; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - compare_exchange_strong( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - platform_fence_before(success_order); - - bool success = platform_cmpxchg64_strong(expected, desired, &v_); - - if (success) { - platform_fence_after(success_order); - } else { - platform_fence_after(failure_order); - } - - return success; - } - - value_type - fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); - return original; - } - - value_type - fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - value_type original = load(memory_order_relaxed); - do { - } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); - return original; - } - - bool - is_lock_free(void) const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_POINTER_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -350,15 +164,20 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -430,9 +249,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; diff --git a/cpp/BoostParts/boost/atomic/detail/config.hpp b/cpp/BoostParts/boost/atomic/detail/config.hpp index 979bdd8f..b1984e52 100644 --- a/cpp/BoostParts/boost/atomic/detail/config.hpp +++ b/cpp/BoostParts/boost/atomic/detail/config.hpp @@ -9,46 +9,8 @@ #include -#if (defined(_MSC_VER) && (_MSC_VER >= 1020)) || defined(__GNUC__) || defined(BOOST_CLANG) || defined(BOOST_INTEL) || defined(__COMO__) || defined(__DMC__) -#define BOOST_ATOMIC_HAS_PRAGMA_ONCE -#endif - -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif -/////////////////////////////////////////////////////////////////////////////// -// Set up dll import/export options -#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \ - !defined(BOOST_ATOMIC_STATIC_LINK) - -#if defined(BOOST_ATOMIC_SOURCE) -#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT -#define BOOST_ATOMIC_BUILD_DLL -#else -#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT -#endif - -#endif // building a shared library - -#ifndef BOOST_ATOMIC_DECL -#define BOOST_ATOMIC_DECL -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Auto library naming -#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \ - !defined(BOOST_ATOMIC_NO_LIB) - -#define BOOST_LIB_NAME boost_atomic - -// tell the auto-link code to select a dll when required: -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK) -#define BOOST_DYN_LINK -#endif - -#include - -#endif // auto-linking disabled - #endif diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-alpha.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-alpha.hpp index 360a9db3..27754997 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-alpha.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-alpha.hpp @@ -12,7 +12,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-armv6plus.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-armv6plus.hpp index c11e5cd8..cccd1111 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-armv6plus.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-armv6plus.hpp @@ -10,11 +10,10 @@ // Copyright (c) 2013 Tim Blechmann // ARM Code by Phil Endecott, based on other architectures. -#include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -67,29 +66,27 @@ namespace detail { // to annotate the conditional instructions. These are ignored in other modes (e.g. v6), // so they can always be present. -#if defined(__thumb__) && !defined(__ARM_ARCH_7A__) -// FIXME also other v7 variants. +#if defined(__thumb__) && !defined(__thumb2__) #define BOOST_ATOMIC_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 1f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "1: " #define BOOST_ATOMIC_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 1f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "1: " - #else // The tmpreg is wasted in this case, which is non-optimal. #define BOOST_ATOMIC_ARM_ASM_START(TMPREG) #define BOOST_ATOMIC_ARM_ASM_END(TMPREG) #endif -#if defined(__ARM_ARCH_7A__) -// FIXME ditto. +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__) #define BOOST_ATOMIC_ARM_DMB "dmb\n" #else #define BOOST_ATOMIC_ARM_DMB "mcr\tp15, 0, r0, c7, c10, 5\n" #endif inline void -arm_barrier(void) +arm_barrier(void) BOOST_NOEXCEPT { int brtmp; - __asm__ __volatile__ ( + __asm__ __volatile__ + ( BOOST_ATOMIC_ARM_ASM_START(%0) BOOST_ATOMIC_ARM_DMB BOOST_ATOMIC_ARM_ASM_END(%0) @@ -98,56 +95,59 @@ arm_barrier(void) } inline void -platform_fence_before(memory_order order) +platform_fence_before(memory_order order) BOOST_NOEXCEPT { - switch(order) { - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - arm_barrier(); - case memory_order_consume: - default:; + switch(order) + { + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + arm_barrier(); + case memory_order_consume: + default:; } } inline void -platform_fence_after(memory_order order) +platform_fence_after(memory_order order) BOOST_NOEXCEPT { - switch(order) { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - arm_barrier(); - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + arm_barrier(); + default:; } } inline void -platform_fence_before_store(memory_order order) +platform_fence_before_store(memory_order order) BOOST_NOEXCEPT { platform_fence_before(order); } inline void -platform_fence_after_store(memory_order order) +platform_fence_after_store(memory_order order) BOOST_NOEXCEPT { if (order == memory_order_seq_cst) arm_barrier(); } inline void -platform_fence_after_load(memory_order order) +platform_fence_after_load(memory_order order) BOOST_NOEXCEPT { platform_fence_after(order); } template inline bool -platform_cmpxchg32(T & expected, T desired, volatile T * ptr) +platform_cmpxchg32(T & expected, T desired, volatile T * ptr) BOOST_NOEXCEPT { int success; int tmp; - __asm__ ( + __asm__ __volatile__ + ( BOOST_ATOMIC_ARM_ASM_START(%2) "mov %1, #0\n" // success = 0 "ldrex %0, %3\n" // expected' = *(&i) @@ -164,7 +164,7 @@ platform_cmpxchg32(T & expected, T desired, volatile T * ptr) : "r" (expected), // %4 "r" (desired) // %5 : "cc" - ); + ); return success; } @@ -175,13 +175,14 @@ platform_cmpxchg32(T & expected, T desired, volatile T * ptr) inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - atomics::detail::arm_barrier(); - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + atomics::detail::arm_barrier(); + default:; } } @@ -195,9 +196,8 @@ atomic_signal_fence(memory_order) class atomic_flag { private: - atomic_flag(const atomic_flag &) /* = delete */ ; - atomic_flag & operator=(const atomic_flag &) /* = delete */ ; uint32_t v_; + public: BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {} @@ -221,7 +221,11 @@ public: atomics::detail::platform_fence_after(order); return expected; } + + BOOST_DELETED_FUNCTION(atomic_flag(const atomic_flag &)) + BOOST_DELETED_FUNCTION(atomic_flag& operator=(const atomic_flag &)) }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } @@ -249,4 +253,3 @@ public: #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */ #endif - diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-atomic.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-atomic.hpp new file mode 100644 index 00000000..5cd7f8f6 --- /dev/null +++ b/cpp/BoostParts/boost/atomic/detail/gcc-atomic.hpp @@ -0,0 +1,1204 @@ +#ifndef BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP +#define BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP + +// Copyright (c) 2013 Andrey Semashev +// +// 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) + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if (defined(__i386__) && defined(__SSE2__)) || defined(__x86_64__) +#define BOOST_ATOMIC_X86_PAUSE() __asm__ __volatile__ ("pause\n") +#endif + +#if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1 +#endif + +#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG16B 1 +#endif + +BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT +{ + return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME : + (order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE : + (order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST))))); +} + +} // namespace detail +} // namespace atomics + +#if __GCC_ATOMIC_BOOL_LOCK_FREE == 2 + +class atomic_flag +{ +private: + atomic_flag(const atomic_flag &) /* = delete */ ; + atomic_flag & operator=(const atomic_flag &) /* = delete */ ; + bool v_; + +public: + BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(false) {} + + bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_test_and_set(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_clear((bool*)&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } +}; + +#define BOOST_ATOMIC_FLAG_LOCK_FREE 2 + +#endif // __GCC_ATOMIC_BOOL_LOCK_FREE == 2 + +} // namespace boost + +#include + +#if !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +#if __GCC_ATOMIC_CHAR_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_CHAR16_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_CHAR32_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_SHORT_LOCK_FREE == 2 +#define BOOST_ATOMIC_SHORT_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_INT_LOCK_FREE == 2 +#define BOOST_ATOMIC_INT_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_LONG_LOCK_FREE == 2 +#define BOOST_ATOMIC_LONG_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_LLONG_LOCK_FREE == 2 +#define BOOST_ATOMIC_LLONG_LOCK_FREE 2 +#endif +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_POINTER_LOCK_FREE == 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_BOOL_LOCK_FREE == 2 +#define BOOST_ATOMIC_BOOL_LOCK_FREE 2 +#endif + +namespace boost { + +#define BOOST_ATOMIC_THREAD_FENCE 2 +BOOST_FORCEINLINE void atomic_thread_fence(memory_order order) +{ + __atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +#define BOOST_ATOMIC_SIGNAL_FENCE 2 +BOOST_FORCEINLINE void atomic_signal_fence(memory_order order) +{ + __atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +namespace atomics { +namespace detail { + +#if defined(BOOST_ATOMIC_CHAR_LOCK_FREE) && BOOST_ATOMIC_CHAR_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint8_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : + v_(reinterpret_cast(v)) + { + } + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v; + __atomic_load(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type r; + __atomic_exchange(&v_, (storage_type*)&v, (storage_type*)&r, atomics::detail::convert_memory_order_to_gcc(order)); + return r; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_CHAR_LOCK_FREE) && BOOST_ATOMIC_CHAR_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_SHORT_LOCK_FREE) && BOOST_ATOMIC_SHORT_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint16_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : + v_(reinterpret_cast(v)) + { + } + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v; + __atomic_load(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type r; + __atomic_exchange(&v_, (storage_type*)&v, (storage_type*)&r, atomics::detail::convert_memory_order_to_gcc(order)); + return r; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_SHORT_LOCK_FREE) && BOOST_ATOMIC_SHORT_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_INT_LOCK_FREE) && BOOST_ATOMIC_INT_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_INT_LOCK_FREE) && BOOST_ATOMIC_INT_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_LLONG_LOCK_FREE) && BOOST_ATOMIC_LLONG_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_LLONG_LOCK_FREE) && BOOST_ATOMIC_LLONG_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +#if defined(BOOST_HAS_INT128) + +typedef boost::uint128_type storage128_type; + +#else // defined(BOOST_HAS_INT128) + +struct BOOST_ALIGNMENT(16) storage128_type +{ + uint64_t data[2]; +}; + +inline bool operator== (storage128_type const& left, storage128_type const& right) +{ + return left.data[0] == right.data[0] && left.data[1] == right.data[1]; +} +inline bool operator!= (storage128_type const& left, storage128_type const& right) +{ + return !(left == right); +} + +#endif // defined(BOOST_HAS_INT128) + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef storage128_type storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + + +/* pointers */ + +#if defined(BOOST_ATOMIC_POINTER_LOCK_FREE) && BOOST_ATOMIC_POINTER_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v * sizeof(T), atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v * sizeof(T), atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef void* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +#endif // defined(BOOST_ATOMIC_POINTER_LOCK_FREE) && BOOST_ATOMIC_POINTER_LOCK_FREE > 0 + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +#endif // BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-cas.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-cas.hpp index 446da378..25626bd5 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-cas.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-cas.hpp @@ -11,11 +11,10 @@ #ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP -#include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -25,16 +24,17 @@ namespace boost { inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_relaxed: - break; - case memory_order_release: - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + break; + case memory_order_release: + case memory_order_consume: + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -56,16 +56,17 @@ platform_fence_after(memory_order) inline void platform_fence_before_store(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_acquire: + case memory_order_consume: + break; + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -79,16 +80,17 @@ platform_fence_after_store(memory_order order) inline void platform_fence_after_load(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_release: + break; + case memory_order_consume: + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -132,6 +134,7 @@ public: return expected; } }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-ppc.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-ppc.hpp index aaeeb96c..e6735dab 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-ppc.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-ppc.hpp @@ -8,11 +8,12 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -65,40 +66,43 @@ namespace detail { inline void ppc_fence_before(memory_order order) { - switch(order) { - case memory_order_release: - case memory_order_acq_rel: + switch(order) + { + case memory_order_release: + case memory_order_acq_rel: #if defined(__powerpc64__) - __asm__ __volatile__ ("lwsync" ::: "memory"); - break; + __asm__ __volatile__ ("lwsync" ::: "memory"); + break; #endif - case memory_order_seq_cst: - __asm__ __volatile__ ("sync" ::: "memory"); - default:; + case memory_order_seq_cst: + __asm__ __volatile__ ("sync" ::: "memory"); + default:; } } inline void ppc_fence_after(memory_order order) { - switch(order) { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("isync"); - case memory_order_consume: - __asm__ __volatile__ ("" ::: "memory"); - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("isync"); + case memory_order_consume: + __asm__ __volatile__ ("" ::: "memory"); + default:; } } inline void ppc_fence_after_store(memory_order order) { - switch(order) { - case memory_order_seq_cst: - __asm__ __volatile__ ("sync"); - default:; + switch(order) + { + case memory_order_seq_cst: + __asm__ __volatile__ ("sync"); + default:; } } @@ -199,13 +203,18 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef int32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -411,22 +420,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -633,22 +649,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef int32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -855,22 +878,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1077,21 +1107,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1292,9 +1329,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -1303,12 +1342,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1509,9 +1553,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -1524,12 +1570,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1681,21 +1732,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1849,9 +1907,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -1860,12 +1920,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -2017,21 +2082,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -2185,9 +2257,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -2198,15 +2272,20 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -2340,26 +2419,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2492,26 +2577,32 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2644,9 +2735,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; @@ -2655,17 +2748,21 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2798,11 +2895,14 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; + #endif } @@ -2812,19 +2912,20 @@ private: inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_acquire: - __asm__ __volatile__ ("isync" ::: "memory"); - break; - case memory_order_release: + switch(order) + { + case memory_order_acquire: + __asm__ __volatile__ ("isync" ::: "memory"); + break; + case memory_order_release: #if defined(__powerpc64__) - __asm__ __volatile__ ("lwsync" ::: "memory"); - break; + __asm__ __volatile__ ("lwsync" ::: "memory"); + break; #endif - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("sync" ::: "memory"); - default:; + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("sync" ::: "memory"); + default:; } } @@ -2832,14 +2933,15 @@ atomic_thread_fence(memory_order order) inline void atomic_signal_fence(memory_order order) { - switch(order) { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("" ::: "memory"); - break; - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("" ::: "memory"); + break; + default:; } } diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-sparcv9.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-sparcv9.hpp index b524403b..b3fc7e6a 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-sparcv9.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-sparcv9.hpp @@ -8,11 +8,12 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -23,53 +24,56 @@ namespace detail { inline void platform_fence_before(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); - /* release */ - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - /* seq */ - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_acquire: + case memory_order_consume: + break; + case memory_order_release: + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + /* release */ + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + /* seq */ + break; } } inline void platform_fence_after(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_acquire: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); - /* acquire */ - break; - case memory_order_consume: - /* consume */ - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - /* seq */ - break; - default:; + switch(order) + { + case memory_order_relaxed: + case memory_order_release: + break; + case memory_order_acquire: + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); + /* acquire */ + break; + case memory_order_consume: + /* consume */ + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + /* seq */ + break; + default:; } } inline void platform_fence_after_store(memory_order order) { - switch(order) { - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - default:; + switch(order) + { + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + default:; } } @@ -141,24 +145,25 @@ namespace boost { inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_relaxed: - break; - case memory_order_release: - __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); - break; - case memory_order_acquire: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); - break; - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); - break; - case memory_order_consume: - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - break; - default:; + switch(order) + { + case memory_order_relaxed: + break; + case memory_order_release: + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + break; + case memory_order_acquire: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); + break; + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); + break; + case memory_order_consume: + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + break; + default:; } } @@ -177,13 +182,18 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef int32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -291,22 +301,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -414,22 +431,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef int32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -537,22 +561,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -660,21 +691,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -780,9 +818,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -791,12 +831,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -876,21 +921,27 @@ public: BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -972,9 +1023,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -983,15 +1036,20 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1064,24 +1122,31 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1154,24 +1219,31 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1244,9 +1316,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; diff --git a/cpp/BoostParts/boost/atomic/detail/gcc-x86.hpp b/cpp/BoostParts/boost/atomic/detail/gcc-x86.hpp index 1cf9d67d..284478de 100644 --- a/cpp/BoostParts/boost/atomic/detail/gcc-x86.hpp +++ b/cpp/BoostParts/boost/atomic/detail/gcc-x86.hpp @@ -8,11 +8,12 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -37,6 +38,10 @@ namespace detail { #define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1 #endif +#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG16B 1 +#endif + inline void platform_fence_before(memory_order order) { @@ -209,8 +214,10 @@ public: #if defined(__x86_64__) || defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B) #define BOOST_ATOMIC_LLONG_LOCK_FREE 2 -#else -#define BOOST_ATOMIC_LLONG_LOCK_FREE 0 +#endif + +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 @@ -257,12 +264,17 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -287,9 +299,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddb %0, %1" : "+q" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -305,7 +320,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgb %0, %1" : "+q" (v), "+m" (v_) ); @@ -322,12 +338,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgb %2, %1" - : "+a" (previous), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgb %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (v_), "=q" (success) : "q" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -350,7 +369,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for(; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -361,7 +380,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -372,7 +391,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -386,21 +405,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -425,9 +451,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddw %0, %1" : "+q" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -443,7 +472,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgw %0, %1" : "+q" (v), "+m" (v_) ); @@ -460,12 +490,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgw %2, %1" - : "+a" (previous), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgw %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (v_), "=q" (success) : "q" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -488,7 +521,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -499,7 +532,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -510,7 +543,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -524,21 +557,28 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -563,9 +603,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddl %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -581,7 +624,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -598,12 +642,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -626,7 +673,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -637,7 +684,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -648,7 +695,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -662,9 +709,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -672,12 +721,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -702,9 +756,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -720,7 +777,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -737,12 +795,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -765,7 +826,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -776,7 +837,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -787,7 +848,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -801,9 +862,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -811,17 +874,23 @@ private: /* pointers */ -#if !defined(__x86_64__) +// NOTE: x32 target is still regarded to as x86_64 and can only be detected by the size of pointers +#if !defined(__x86_64__) || (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4) template class base_atomic { +private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -844,7 +913,8 @@ public: value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -858,12 +928,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -889,10 +962,13 @@ public: fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( - "lock ; xaddl %0, %1" - : "+r" (v), "+m" (v_) - ); + __asm__ __volatile__ + ( + "lock ; xaddl %0, %1" + : "+r" (v), "+m" (v_) + : + : "cc" + ); platform_fence_after(order); return reinterpret_cast(v); } @@ -904,21 +980,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -943,7 +1026,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -960,12 +1044,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -989,9 +1076,12 @@ public: { v = v * sizeof(*v_); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddl %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1010,9 +1100,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -1021,12 +1113,17 @@ private: template class base_atomic { +private: typedef base_atomic this_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1049,7 +1146,8 @@ public: value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -1063,12 +1161,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -1094,9 +1195,12 @@ public: fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1109,21 +1213,28 @@ public: } BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; - typedef ptrdiff_t difference_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1148,7 +1259,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -1165,12 +1277,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -1194,9 +1309,12 @@ public: { v = v * sizeof(*v_); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1215,9 +1333,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -1226,14 +1346,20 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint8_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) - {} - base_atomic(void) {} + { + } void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1264,7 +1390,8 @@ public: storage_type tmp; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgb %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1286,12 +1413,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgb %2, %1" - : "+a" (previous_s), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgb %3, %1\n\t" + "sete %2" + : "+a" (previous_s), "+m" (v_), "=q" (success) : "q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1317,23 +1447,31 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint16_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) - {} - base_atomic(void) {} + { + } void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1364,7 +1502,8 @@ public: storage_type tmp; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgw %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1386,12 +1525,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgw %2, %1" - : "+a" (previous_s), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgw %3, %1\n\t" + "sete %2" + : "+a" (previous_s), "+m" (v_), "=q" (success) : "q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1417,24 +1559,31 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1465,7 +1614,8 @@ public: storage_type tmp = 0; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1487,12 +1637,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous_s), "+m" (v_) - : "q" (desired_s) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous_s), "+m,m" (v_), "=q,m" (success) + : "q,q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1518,9 +1671,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; @@ -1528,15 +1683,20 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1567,7 +1727,8 @@ public: storage_type tmp = 0; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1589,12 +1750,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous_s), "+m" (v_) - : "q" (desired_s) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous_s), "+m,m" (v_), "=q,m" (success) + : "q,q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1620,9 +1784,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; #endif @@ -1640,7 +1806,6 @@ platform_cmpxchg64_strong(T & expected, T desired, volatile T * ptr) BOOST_NOEXC return result; #else uint32_t scratch; - T prev = expected; /* Make sure ebx is saved and restored properly in case this object is compiled as "position independent". Since programmers on x86 tend to forget specifying -DPIC or @@ -1655,16 +1820,18 @@ platform_cmpxchg64_strong(T & expected, T desired, volatile T * ptr) BOOST_NOEXC In theory, could push/pop ebx onto/off the stack, but movs to a prepared stack slot turn out to be faster. */ - __asm__ __volatile__ ( - "movl %%ebx, %1\n" - "movl %2, %%ebx\n" - "lock; cmpxchg8b 0(%4)\n" - "movl %1, %%ebx\n" - : "=A" (prev), "=m" (scratch) - : "D" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), "S" (ptr), "0" (prev) - : "memory"); - bool success = (prev == expected); - expected = prev; + bool success; + __asm__ __volatile__ + ( + "movl %%ebx, %[scratch]\n\t" + "movl %[desired_lo], %%ebx\n\t" + "lock; cmpxchg8b %[dest]\n\t" + "movl %[scratch], %%ebx\n\t" + "sete %[success]" + : "+A,A,A,A,A,A" (expected), [dest] "+m,m,m,m,m,m" (*ptr), [scratch] "=m,m,m,m,m,m" (scratch), [success] "=q,m,q,m,q,m" (success) + : [desired_lo] "S,S,D,D,m,m" ((uint32_t)desired), "c,c,c,c,c,c" ((uint32_t)(desired >> 32)) + : "memory", "cc" + ); return success; #endif } @@ -1686,11 +1853,11 @@ platform_store64(T value, volatile T * ptr) BOOST_NOEXCEPT #if defined(__SSE2__) __asm__ __volatile__ ( - "movq %1, %%xmm0\n\t" - "movq %%xmm0, %0\n\t" + "movq %1, %%xmm4\n\t" + "movq %%xmm4, %0\n\t" : "=m" (*ptr) : "m" (value) - : "memory", "xmm0" + : "memory", "xmm4" ); #else __asm__ __volatile__ @@ -1705,11 +1872,21 @@ platform_store64(T value, volatile T * ptr) BOOST_NOEXCEPT } else { - T expected = *ptr; - while (!platform_cmpxchg64_strong(expected, value, ptr)) - { - BOOST_ATOMIC_X86_PAUSE(); - } + uint32_t scratch; + __asm__ __volatile__ + ( + "movl %%ebx, %[scratch]\n\t" + "movl %[value_lo], %%ebx\n\t" + "movl 0(%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b 0(%[dest])\n\t" + "jne 1b\n\t" + "movl %[scratch], %%ebx" + : [scratch] "=m,m" (scratch) + : [value_lo] "a,a" ((uint32_t)value), "c,c" ((uint32_t)(value >> 32)), [dest] "D,S" (ptr) + : "memory", "cc", "edx" + ); } } @@ -1717,18 +1894,18 @@ template inline T platform_load64(const volatile T * ptr) BOOST_NOEXCEPT { - T value = T(); + T value; if (((uint32_t)ptr & 0x00000007) == 0) { #if defined(__SSE2__) __asm__ __volatile__ ( - "movq %1, %%xmm0\n\t" - "movq %%xmm0, %0\n\t" + "movq %1, %%xmm4\n\t" + "movq %%xmm4, %0\n\t" : "=m" (value) : "m" (*ptr) - : "memory", "xmm0" + : "memory", "xmm4" ); #else __asm__ __volatile__ @@ -1744,7 +1921,16 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT else { // We don't care for comparison result here; the previous value will be stored into value anyway. - platform_cmpxchg64_strong(value, value, const_cast(ptr)); + // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. + __asm__ __volatile__ + ( + "movl %%ebx, %%eax\n\t" + "movl %%ecx, %%edx\n\t" + "lock; cmpxchg8b %[dest]" + : "=&A" (value) + : [dest] "m" (*ptr) + : "cc" + ); } return value; @@ -1752,6 +1938,66 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT #endif +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + +template +inline bool +platform_cmpxchg128_strong(T& expected, T desired, volatile T* ptr) BOOST_NOEXCEPT +{ + uint64_t const* p_desired = (uint64_t const*)&desired; + bool success; + __asm__ __volatile__ + ( + "lock; cmpxchg16b %[dest]\n\t" + "sete %[success]" + : "+A,A" (expected), [dest] "+m,m" (*ptr), [success] "=q,m" (success) + : "b,b" (p_desired[0]), "c,c" (p_desired[1]) + : "memory", "cc" + ); + return success; +} + +template +inline void +platform_store128(T value, volatile T* ptr) BOOST_NOEXCEPT +{ + uint64_t const* p_value = (uint64_t const*)&value; + __asm__ __volatile__ + ( + "movq 0(%[dest]), %%rax\n\t" + "movq 8(%[dest]), %%rdx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg16b 0(%[dest])\n\t" + "jne 1b" + : + : "b" (p_value[0]), "c" (p_value[1]), [dest] "r" (ptr) + : "memory", "cc", "rax", "rdx" + ); +} + +template +inline T +platform_load128(const volatile T* ptr) BOOST_NOEXCEPT +{ + T value; + + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b. + __asm__ __volatile__ + ( + "movq %%rbx, %%rax\n\t" + "movq %%rcx, %%rdx\n\t" + "lock; cmpxchg16b %[dest]" + : "=&A" (value) + : [dest] "m" (*ptr) + : "cc" + ); + + return value; +} + +#endif // defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + } } } @@ -1761,6 +2007,11 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT #include #endif +/* pull in 128-bit atomic type using cmpxchg16b above */ +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 +#include +#endif + #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */ #endif diff --git a/cpp/BoostParts/boost/atomic/detail/generic-cas.hpp b/cpp/BoostParts/boost/atomic/detail/generic-cas.hpp index f8cc3cc9..cf4a3d79 100644 --- a/cpp/BoostParts/boost/atomic/detail/generic-cas.hpp +++ b/cpp/BoostParts/boost/atomic/detail/generic-cas.hpp @@ -14,7 +14,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/cpp/BoostParts/boost/atomic/detail/interlocked.hpp b/cpp/BoostParts/boost/atomic/detail/interlocked.hpp index 2cf21a1b..ae8518df 100644 --- a/cpp/BoostParts/boost/atomic/detail/interlocked.hpp +++ b/cpp/BoostParts/boost/atomic/detail/interlocked.hpp @@ -10,7 +10,7 @@ #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -43,6 +43,11 @@ #define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg)) +#if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64) +#pragma intrinsic(_InterlockedCompareExchange64) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#endif + #if _MSC_VER >= 1600 // MSVC 2010 and later provide intrinsics for 8 and 16 bit integers. @@ -81,14 +86,12 @@ #if defined(_M_AMD64) || defined(_M_IA64) -#pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedXor64) -#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) diff --git a/cpp/BoostParts/boost/atomic/detail/link.hpp b/cpp/BoostParts/boost/atomic/detail/link.hpp new file mode 100644 index 00000000..25a4caf2 --- /dev/null +++ b/cpp/BoostParts/boost/atomic/detail/link.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_ATOMIC_DETAIL_LINK_HPP +#define BOOST_ATOMIC_DETAIL_LINK_HPP + +// Copyright (c) 2012 Hartmut Kaiser +// +// 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) + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Set up dll import/export options +#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \ + !defined(BOOST_ATOMIC_STATIC_LINK) + +#if defined(BOOST_ATOMIC_SOURCE) +#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT +#define BOOST_ATOMIC_BUILD_DLL +#else +#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT +#endif + +#endif // building a shared library + +#ifndef BOOST_ATOMIC_DECL +#define BOOST_ATOMIC_DECL +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Auto library naming +#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_ATOMIC_NO_LIB) + +#define BOOST_LIB_NAME boost_atomic + +// tell the auto-link code to select a dll when required: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK) +#define BOOST_DYN_LINK +#endif + +#include + +#endif // auto-linking disabled + +#endif diff --git a/cpp/BoostParts/boost/atomic/detail/linux-arm.hpp b/cpp/BoostParts/boost/atomic/detail/linux-arm.hpp index af1606e2..d39dcd0e 100644 --- a/cpp/BoostParts/boost/atomic/detail/linux-arm.hpp +++ b/cpp/BoostParts/boost/atomic/detail/linux-arm.hpp @@ -36,7 +36,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -163,6 +163,7 @@ public: return expected; } }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } diff --git a/cpp/BoostParts/boost/atomic/detail/lockpool.hpp b/cpp/BoostParts/boost/atomic/detail/lockpool.hpp index b86cfae2..42464866 100644 --- a/cpp/BoostParts/boost/atomic/detail/lockpool.hpp +++ b/cpp/BoostParts/boost/atomic/detail/lockpool.hpp @@ -8,11 +8,12 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include #ifndef BOOST_ATOMIC_FLAG_LOCK_FREE -#include +#include #endif -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -25,25 +26,19 @@ namespace detail { class lockpool { public: - typedef mutex lock_type; - class scoped_lock + typedef boost::detail::lightweight_mutex lock_type; + class scoped_lock : + public lock_type::scoped_lock { - private: - lock_type& mtx_; - - scoped_lock(scoped_lock const&) /* = delete */; - scoped_lock& operator=(scoped_lock const&) /* = delete */; + typedef lock_type::scoped_lock base_type; public: - explicit - scoped_lock(const volatile void * addr) : mtx_(get_lock_for(addr)) + explicit scoped_lock(const volatile void * addr) : base_type(get_lock_for(addr)) { - mtx_.lock(); - } - ~scoped_lock() - { - mtx_.unlock(); } + + BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&)) + BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&)) }; private: @@ -61,10 +56,6 @@ public: { private: atomic_flag& flag_; - uint8_t padding[128 - sizeof(atomic_flag)]; - - scoped_lock(const scoped_lock &) /* = delete */; - scoped_lock& operator=(const scoped_lock &) /* = delete */; public: explicit @@ -82,6 +73,9 @@ public: { flag_.clear(memory_order_release); } + + BOOST_DELETED_FUNCTION(scoped_lock(const scoped_lock &)) + BOOST_DELETED_FUNCTION(scoped_lock& operator=(const scoped_lock &)) }; private: diff --git a/cpp/BoostParts/boost/atomic/detail/platform.hpp b/cpp/BoostParts/boost/atomic/detail/platform.hpp index a31ececa..3dfb73d7 100644 --- a/cpp/BoostParts/boost/atomic/detail/platform.hpp +++ b/cpp/BoostParts/boost/atomic/detail/platform.hpp @@ -11,11 +11,17 @@ #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +// Intel compiler does not support __atomic* intrinsics properly, although defines them (tested with 13.0.1 and 13.1.1 on Linux) +#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(BOOST_INTEL_CXX_VERSION))\ + || (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302)) + + #include + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #include @@ -32,7 +38,10 @@ // I don't know how complete it is. #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_7A__)) + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)) #include diff --git a/cpp/BoostParts/boost/atomic/detail/type-classification.hpp b/cpp/BoostParts/boost/atomic/detail/type-classification.hpp index f7c2f8bf..98bc3113 100644 --- a/cpp/BoostParts/boost/atomic/detail/type-classification.hpp +++ b/cpp/BoostParts/boost/atomic/detail/type-classification.hpp @@ -10,7 +10,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -36,7 +36,7 @@ struct storage_size_of enum _ { size = sizeof(T), - value = (size == 3 ? 4 : (size == 5 || size == 6 || size == 7 ? 8 : size)) + value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size))) }; }; diff --git a/cpp/BoostParts/boost/atomic/detail/windows.hpp b/cpp/BoostParts/boost/atomic/detail/windows.hpp index 0fa97120..a8dc4f84 100644 --- a/cpp/BoostParts/boost/atomic/detail/windows.hpp +++ b/cpp/BoostParts/boost/atomic/detail/windows.hpp @@ -9,13 +9,14 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -33,6 +34,10 @@ extern "C" void _mm_pause(void); #define BOOST_ATOMIC_X86_PAUSE() #endif +#if defined(_M_IX86) && _M_IX86 >= 500 +#define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1 +#endif + // Define hardware barriers #if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) extern "C" void _mm_mfence(void); @@ -41,7 +46,7 @@ extern "C" void _mm_mfence(void); // Define compiler barriers #if defined(__INTEL_COMPILER) -#define BOOST_ATOMIC_COMPILER_BARRIER __memory_barrier(); +#define BOOST_ATOMIC_COMPILER_BARRIER() __memory_barrier() #elif defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE) extern "C" void _ReadWriteBarrier(void); #pragma intrinsic(_ReadWriteBarrier) @@ -67,17 +72,6 @@ BOOST_FORCEINLINE void hardware_full_fence(void) #endif } -// Define compiler barriers -#if defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE) -extern "C" void _ReadWriteBarrier(); -#pragma intrinsic(_ReadWriteBarrier) -#define BOOST_ATOMIC_COMPILER_BARRIER() _ReadWriteBarrier() -#endif - -#ifndef BOOST_ATOMIC_COMPILER_BARRIER -#define BOOST_ATOMIC_COMPILER_BARRIER() -#endif - BOOST_FORCEINLINE void platform_fence_before(memory_order) { @@ -179,7 +173,7 @@ public: #define BOOST_ATOMIC_SHORT_LOCK_FREE 2 #define BOOST_ATOMIC_INT_LOCK_FREE 2 #define BOOST_ATOMIC_LONG_LOCK_FREE 2 -#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B) || defined(_M_AMD64) || defined(_M_IA64) #define BOOST_ATOMIC_LLONG_LOCK_FREE 2 #else #define BOOST_ATOMIC_LLONG_LOCK_FREE 0 @@ -200,6 +194,7 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 @@ -208,9 +203,13 @@ class base_atomic typedef uint32_t storage_type; #endif typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -373,9 +372,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; @@ -386,6 +387,7 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 @@ -394,9 +396,13 @@ class base_atomic typedef uint32_t storage_type; #endif typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -559,22 +565,29 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef value_type storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -710,24 +723,570 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; -#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) +// MSVC 2012 fails to recognize sizeof(T) as a constant expression in template specializations +enum msvc_sizeof_pointer_workaround { sizeof_pointer = sizeof(void*) }; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef std::ptrdiff_t difference_type; + typedef void* value_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) { + platform_fence_before(order); + const_cast(v_) = v; + } else { + exchange(v, order); + } + } + + value_type load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT + { + value_type v = const_cast(v_); + platform_fence_after_load(order); + return v; + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before(order); + v = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(&v_, v); + platform_fence_after(order); + return v; + } + + bool compare_exchange_strong(value_type & expected, value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + value_type previous = expected; + platform_fence_before(success_order); + value_type oldval = (value_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&v_, desired, previous); + bool success = (previous == oldval); + if (success) + platform_fence_after(success_order); + else + platform_fence_after(failure_order); + expected = oldval; + return success; + } + + bool compare_exchange_weak(value_type & expected, value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + is_lock_free(void)const volatile BOOST_NOEXCEPT + { + return true; + } + + value_type + fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before(order); + value_type res = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(&v_, v); + platform_fence_after(order); + return res; + } + + value_type + fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return fetch_add(-v, order); + } + + BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) { + platform_fence_before(order); + const_cast(v_) = v; + } else { + exchange(v, order); + } + } + + value_type + load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT + { + value_type v = const_cast(v_); + platform_fence_after_load(order); + return v; + } + + value_type + exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before(order); + v = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(&v_, v); + platform_fence_after(order); + return v; + } + + bool + compare_exchange_strong( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + value_type previous = expected; + platform_fence_before(success_order); + value_type oldval = (value_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&v_, desired, previous); + bool success = (previous == oldval); + if (success) + platform_fence_after(success_order); + else + platform_fence_after(failure_order); + expected = oldval; + return success; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + value_type + fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + v = v * sizeof(*v_); + platform_fence_before(order); + value_type res = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(&v_, v); + platform_fence_after(order); + return res; + } + + value_type + fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return fetch_add(-v, order); + } + + bool + is_lock_free(void)const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 + typedef uint8_t storage_type; +#else + typedef uint32_t storage_type; +#endif + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) + { + } +#else + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } +#endif + + void + store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); + const_cast(v_) = tmp; + } else { + exchange(v, order); + } + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = const_cast(v_); + platform_fence_after_load(order); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type + exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); +#ifdef BOOST_ATOMIC_INTERLOCKED_EXCHANGE8 + tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&v_, tmp)); +#else + tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); +#endif + platform_fence_after(order); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool + compare_exchange_strong( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + platform_fence_before(success_order); +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 + storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&v_, desired_s, expected_s)); +#else + storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); +#endif + bool success = (oldval == expected_s); + if (success) + platform_fence_after(success_order); + else + platform_fence_after(failure_order); + memcpy(&expected, &oldval, sizeof(value_type)); + return success; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 + typedef uint16_t storage_type; +#else + typedef uint32_t storage_type; +#endif + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) + { + } +#else + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } +#endif + + void + store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); + const_cast(v_) = tmp; + } else { + exchange(v, order); + } + } + + value_type + load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT + { + storage_type tmp = const_cast(v_); + platform_fence_after_load(order); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type + exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); +#ifdef BOOST_ATOMIC_INTERLOCKED_EXCHANGE16 + tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&v_, tmp)); +#else + tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); +#endif + platform_fence_after(order); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool + compare_exchange_strong( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + platform_fence_before(success_order); +#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 + storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&v_, desired_s, expected_s)); +#else + storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); +#endif + bool success = (oldval == expected_s); + if (success) + platform_fence_after(success_order); + else + platform_fence_after(failure_order); + memcpy(&expected, &oldval, sizeof(value_type)); + return success; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + is_lock_free(void)const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void + store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); + const_cast(v_) = tmp; + } else { + exchange(v, order); + } + } + + value_type + load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT + { + storage_type tmp = const_cast(v_); + platform_fence_after_load(order); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type + exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + platform_fence_before(order); + tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); + platform_fence_after(order); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool + compare_exchange_strong( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + platform_fence_before(success_order); + storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); + bool success = (oldval == expected_s); + if (success) + platform_fence_after(success_order); + else + platform_fence_after(failure_order); + memcpy(&expected, &oldval, sizeof(value_type)); + return success; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#if defined(_M_AMD64) || defined(_M_IA64) template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef value_type storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -741,7 +1300,7 @@ public: } value_type - load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT { value_type v = static_cast< value_type >(v_); platform_fence_after_load(order); @@ -863,531 +1422,31 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; -#endif // defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) - -// MSVC 2012 fails to recognize sizeof(T) as a constant expression in template specializations -enum msvc_sizeof_pointer_workaround { sizeof_pointer = sizeof(void*) }; - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef ptrdiff_t difference_type; - typedef void* value_type; -public: - BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} - - void - store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - if (order != memory_order_seq_cst) { - platform_fence_before(order); - const_cast(v_) = v; - } else { - exchange(v, order); - } - } - - value_type load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT - { - value_type v = const_cast(v_); - platform_fence_after_load(order); - return v; - } - - value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - platform_fence_before(order); - v = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(&v_, v); - platform_fence_after(order); - return v; - } - - bool compare_exchange_strong(value_type & expected, value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - value_type previous = expected; - platform_fence_before(success_order); - value_type oldval = (value_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&v_, desired, previous); - bool success = (previous == oldval); - if (success) - platform_fence_after(success_order); - else - platform_fence_after(failure_order); - expected = oldval; - return success; - } - - bool compare_exchange_weak(value_type & expected, value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - is_lock_free(void)const volatile BOOST_NOEXCEPT - { - return true; - } - - value_type - fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - platform_fence_before(order); - value_type res = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(&v_, v); - platform_fence_after(order); - return res; - } - - value_type - fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - return fetch_add(-v, order); - } - - BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - value_type v_; -}; - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef T* value_type; - typedef ptrdiff_t difference_type; -public: - BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} - base_atomic(void) {} - - void - store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - if (order != memory_order_seq_cst) { - platform_fence_before(order); - const_cast(v_) = v; - } else { - exchange(v, order); - } - } - - value_type - load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT - { - value_type v = const_cast(v_); - platform_fence_after_load(order); - return v; - } - - value_type - exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - platform_fence_before(order); - v = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(&v_, v); - platform_fence_after(order); - return v; - } - - bool - compare_exchange_strong( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - value_type previous = expected; - platform_fence_before(success_order); - value_type oldval = (value_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&v_, desired, previous); - bool success = (previous == oldval); - if (success) - platform_fence_after(success_order); - else - platform_fence_after(failure_order); - expected = oldval; - return success; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - value_type - fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - v = v * sizeof(*v_); - platform_fence_before(order); - value_type res = (value_type)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(&v_, v); - platform_fence_after(order); - return res; - } - - value_type - fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - return fetch_add(-v, order); - } - - bool - is_lock_free(void)const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_POINTER_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - value_type v_; -}; - - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef T value_type; -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 - typedef uint8_t storage_type; -#else - typedef uint32_t storage_type; -#endif -public: -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 - BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) - { - } -#else - explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) - { - memcpy(&v_, &v, sizeof(value_type)); - } -#endif - base_atomic(void) {} - - void - store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - if (order != memory_order_seq_cst) { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); - const_cast(v_) = tmp; - } else { - exchange(v, order); - } - } - - value_type - load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT - { - storage_type tmp = const_cast(v_); - platform_fence_after_load(order); - value_type v; - memcpy(&v, &tmp, sizeof(value_type)); - return v; - } - - value_type - exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); -#ifdef BOOST_ATOMIC_INTERLOCKED_EXCHANGE8 - tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&v_, tmp)); -#else - tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); -#endif - platform_fence_after(order); - value_type res; - memcpy(&res, &tmp, sizeof(value_type)); - return res; - } - - bool - compare_exchange_strong( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - storage_type expected_s = 0, desired_s = 0; - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - platform_fence_before(success_order); -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 - storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&v_, desired_s, expected_s)); -#else - storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); -#endif - bool success = (oldval == expected_s); - if (success) - platform_fence_after(success_order); - else - platform_fence_after(failure_order); - memcpy(&expected, &oldval, sizeof(value_type)); - return success; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - is_lock_free(void) const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_BASE_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - storage_type v_; -}; - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef T value_type; -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 - typedef uint16_t storage_type; -#else - typedef uint32_t storage_type; -#endif -public: -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 - BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) - { - } -#else - explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) - { - memcpy(&v_, &v, sizeof(value_type)); - } -#endif - - base_atomic(void) {} - - void - store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - if (order != memory_order_seq_cst) { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); - const_cast(v_) = tmp; - } else { - exchange(v, order); - } - } - - value_type - load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT - { - storage_type tmp = const_cast(v_); - platform_fence_after_load(order); - value_type v; - memcpy(&v, &tmp, sizeof(value_type)); - return v; - } - - value_type - exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); -#ifdef BOOST_ATOMIC_INTERLOCKED_EXCHANGE16 - tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&v_, tmp)); -#else - tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); -#endif - platform_fence_after(order); - value_type res; - memcpy(&res, &tmp, sizeof(value_type)); - return res; - } - - bool - compare_exchange_strong( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - storage_type expected_s = 0, desired_s = 0; - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - platform_fence_before(success_order); -#ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 - storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&v_, desired_s, expected_s)); -#else - storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); -#endif - bool success = (oldval == expected_s); - if (success) - platform_fence_after(success_order); - else - platform_fence_after(failure_order); - memcpy(&expected, &oldval, sizeof(value_type)); - return success; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - is_lock_free(void)const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_BASE_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - storage_type v_; -}; - -template -class base_atomic -{ - typedef base_atomic this_type; - typedef T value_type; - typedef uint32_t storage_type; -public: - explicit base_atomic(value_type const& v) : v_(0) - { - memcpy(&v_, &v, sizeof(value_type)); - } - base_atomic(void) {} - - void - store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - if (order != memory_order_seq_cst) { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); - const_cast(v_) = tmp; - } else { - exchange(v, order); - } - } - - value_type - load(memory_order order = memory_order_seq_cst)const volatile BOOST_NOEXCEPT - { - storage_type tmp = const_cast(v_); - platform_fence_after_load(order); - value_type v; - memcpy(&v, &tmp, sizeof(value_type)); - return v; - } - - value_type - exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT - { - storage_type tmp = 0; - memcpy(&tmp, &v, sizeof(value_type)); - platform_fence_before(order); - tmp = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&v_, tmp)); - platform_fence_after(order); - value_type res; - memcpy(&res, &tmp, sizeof(value_type)); - return res; - } - - bool - compare_exchange_strong( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - storage_type expected_s = 0, desired_s = 0; - memcpy(&expected_s, &expected, sizeof(value_type)); - memcpy(&desired_s, &desired, sizeof(value_type)); - platform_fence_before(success_order); - storage_type oldval = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&v_, desired_s, expected_s)); - bool success = (oldval == expected_s); - if (success) - platform_fence_after(success_order); - else - platform_fence_after(failure_order); - memcpy(&expected, &oldval, sizeof(value_type)); - return success; - } - - bool - compare_exchange_weak( - value_type & expected, - value_type const& desired, - memory_order success_order, - memory_order failure_order) volatile BOOST_NOEXCEPT - { - return compare_exchange_strong(expected, desired, success_order, failure_order); - } - - bool - is_lock_free(void)const volatile BOOST_NOEXCEPT - { - return true; - } - - BOOST_ATOMIC_DECLARE_BASE_OPERATORS -private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - storage_type v_; -}; - -#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) - template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1463,18 +1522,144 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; storage_type v_; }; -#endif // defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) +#elif defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B) + +template +inline bool +platform_cmpxchg64_strong(T & expected, T desired, volatile T * p) BOOST_NOEXCEPT +{ +#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) + const T oldval = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(p, desired, expected); + const bool result = (oldval == expected); + expected = oldval; + return result; +#else + bool result; + __asm + { + mov edi, p + mov esi, expected + mov ebx, dword ptr [desired] + mov ecx, dword ptr [desired + 4] + mov eax, dword ptr [esi] + mov edx, dword ptr [esi + 4] + lock cmpxchg8b qword ptr [edi] + mov dword ptr [esi], eax + mov dword ptr [esi + 4], edx + sete result + }; + return result; +#endif +} + +// Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations: +// +// The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically: +// * Reading or writing a quadword aligned on a 64-bit boundary +// +// Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations +// have at least 8 byte alignment. The only unfortunate case is when atomic is placeod on the stack and it is not 8-byte aligned (like on 32 bit Windows). + +template +inline void +platform_store64(T value, volatile T * p) BOOST_NOEXCEPT +{ + if (((uint32_t)p & 0x00000007) == 0) + { +#if defined(_M_IX86_FP) && _M_IX86_FP >= 2 + __asm + { + mov edx, p + movq xmm4, value + movq qword ptr [edx], xmm4 + }; +#else + __asm + { + mov edx, p + fild value + fistp qword ptr [edx] + }; +#endif + } + else + { + __asm + { + mov edi, p + mov ebx, dword ptr [value] + mov ecx, dword ptr [value + 4] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + 4] + align 16 +again: + lock cmpxchg8b qword ptr [edi] + jne again + }; + } +} + +template +inline T +platform_load64(const volatile T * p) BOOST_NOEXCEPT +{ + T value; + + if (((uint32_t)p & 0x00000007) == 0) + { +#if defined(_M_IX86_FP) && _M_IX86_FP >= 2 + __asm + { + mov edx, p + movq xmm4, qword ptr [edx] + movq value, xmm4 + }; +#else + __asm + { + mov edx, p + fild qword ptr [edx] + fistp value + }; +#endif + } + else + { + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. + __asm + { + mov edi, p + mov eax, ebx + mov edx, ecx + lock cmpxchg8b qword ptr [edi] + mov dword ptr [value], eax + mov dword ptr [value + 4], edx + }; + } + + return value; +} + +#endif } // namespace detail } // namespace atomics } // namespace boost +/* pull in 64-bit atomic type using cmpxchg8b above */ +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B) +#include +#endif + #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */ #ifdef _MSC_VER diff --git a/cpp/BoostParts/boost/chrono/detail/inlined/win/chrono.hpp b/cpp/BoostParts/boost/chrono/detail/inlined/win/chrono.hpp index 17dae964..fcb5b290 100644 --- a/cpp/BoostParts/boost/chrono/detail/inlined/win/chrono.hpp +++ b/cpp/BoostParts/boost/chrono/detail/inlined/win/chrono.hpp @@ -12,9 +12,9 @@ #ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP #define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP -#include -#include -#include +#include +#include +#include namespace boost { @@ -25,8 +25,8 @@ namespace chrono_detail BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT { - boost::detail::win32::LARGE_INTEGER_ freq; - if ( !boost::detail::win32::QueryPerformanceFrequency( &freq ) ) + boost::detail::winapi::LARGE_INTEGER_ freq; + if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) ) return 0.0L; return double(1000000000.0L / freq.QuadPart); } @@ -37,9 +37,9 @@ namespace chrono_detail { static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); - boost::detail::win32::LARGE_INTEGER_ pcount; + boost::detail::winapi::LARGE_INTEGER_ pcount; if ( (nanosecs_per_tic <= 0.0L) || - (!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) + (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) ) { BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); return steady_clock::time_point(); @@ -55,14 +55,14 @@ namespace chrono_detail { static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); - boost::detail::win32::LARGE_INTEGER_ pcount; + boost::detail::winapi::LARGE_INTEGER_ pcount; if ( (nanosecs_per_tic <= 0.0L) - || (!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) + || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) ) { - boost::detail::win32::DWORD_ cause = + boost::detail::winapi::DWORD_ cause = ((nanosecs_per_tic <= 0.0L) ? ERROR_NOT_SUPPORTED - : boost::detail::win32::GetLastError()); + : boost::detail::winapi::GetLastError()); if (BOOST_CHRONO_IS_THROWS(ec)) { boost::throw_exception( system::system_error( @@ -89,15 +89,8 @@ namespace chrono_detail BOOST_CHRONO_INLINE system_clock::time_point system_clock::now() BOOST_NOEXCEPT { - boost::detail::win32::FILETIME_ ft; - #if defined(UNDER_CE) - // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps. - boost::detail::win32::SYSTEMTIME_ st; - boost::detail::win32::GetSystemTime( &st ); - boost::detail::win32::SystemTimeToFileTime( &st, &ft ); - #else - boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails - #endif + boost::detail::winapi::FILETIME_ ft; + boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails return system_clock::time_point( system_clock::duration( ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) @@ -110,21 +103,17 @@ namespace chrono_detail BOOST_CHRONO_INLINE system_clock::time_point system_clock::now( system::error_code & ec ) { - boost::detail::win32::FILETIME_ ft; - #if defined(UNDER_CE) - // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps. - boost::detail::win32::SYSTEMTIME_ st; - boost::detail::win32::GetSystemTime( &st ); - boost::detail::win32::SystemTimeToFileTime( &st, &ft ); - #else - boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails - #endif + boost::detail::winapi::FILETIME_ ft; + boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails if (!BOOST_CHRONO_IS_THROWS(ec)) { ec.clear(); } - return time_point(duration( - (static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)); + return system_clock::time_point( + system_clock::duration( + ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) + -116444736000000000LL + )); } #endif @@ -132,7 +121,6 @@ namespace chrono_detail std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT { __int64 temp = t.time_since_epoch().count(); - temp /= 10000000; return static_cast( temp ); } @@ -142,7 +130,6 @@ namespace chrono_detail { __int64 temp = t; temp *= 10000000; - return time_point(duration(temp)); } diff --git a/cpp/BoostParts/boost/circular_buffer/base.hpp b/cpp/BoostParts/boost/circular_buffer/base.hpp index 4893cb20..eaad68d1 100644 --- a/cpp/BoostParts/boost/circular_buffer/base.hpp +++ b/cpp/BoostParts/boost/circular_buffer/base.hpp @@ -1,6 +1,9 @@ // Implementation of the base circular buffer. // Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed. +// Copyright (c) 2013 Antony Polukhin // Move semantics implementation. + // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +16,7 @@ #pragma once #endif +#include #include #include #include @@ -21,12 +25,15 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include -#if !defined(BOOST_NO_EXCEPTIONS) - #include -#endif +#include #if BOOST_CB_ENABLE_DEBUG #include #endif @@ -40,24 +47,26 @@ namespace std { } #endif + + namespace boost { /*! \class circular_buffer \brief Circular buffer - a STL compliant container. - \param T The type of the elements stored in the circular_buffer. + \tparam T The type of the elements stored in the circular_buffer. \par Type Requirements T The T has to be - SGIAssignable (SGI STL defined combination of - Assignable and CopyConstructible). + SGIAssignable (SGI STL defined combination of + Assignable and CopyConstructible). Moreover T has to be DefaultConstructible if supplied as a default parameter when invoking some of the circular_buffer's methods e.g. insert(iterator pos, const value_type& item = %value_type()). And EqualityComparable and/or - LessThanComparable if the circular_buffer + LessThanComparable if the circular_buffer will be compared with another container. - \param Alloc The allocator type used for all internal memory management. + \tparam Alloc The allocator type used for all internal memory management. \par Type Requirements Alloc The Alloc has to meet the allocator requirements imposed by STL. \par Default Alloc @@ -75,11 +84,23 @@ class circular_buffer /*! \endcond */ { -// Requirements - BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); + // Requirements + //BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept); + + + //BOOST_CONCEPT_ASSERT((Assignable)); + //BOOST_CONCEPT_ASSERT((CopyConstructible)); + //BOOST_CONCEPT_ASSERT((DefaultConstructible)); + + // Required if the circular_buffer will be compared with anther container. + //BOOST_CONCEPT_ASSERT((EqualityComparable)); + //BOOST_CONCEPT_ASSERT((LessThanComparable)); public: // Basic types + + //! The type of this circular_buffer. + typedef circular_buffer this_type; //! The type of elements stored in the circular_buffer. typedef typename Alloc::value_type value_type; @@ -145,20 +166,40 @@ public: //! The capacity type. /*! - (Same as size_type - defined for consistency with the - circular_buffer_space_optimized.) + (Same as size_type - defined for consistency with the __cbso class. + */ + // circular_buffer_space_optimized.) + typedef size_type capacity_type; // Helper types - // A type representing the "best" way to pass the value_type to a method. - typedef typename call_traits::param_type param_value_type; + //! A type representing the "best" way to pass the value_type to a method. + typedef const value_type& param_value_type; - // A type representing the "best" way to return the value_type from a const method. - typedef typename call_traits::param_type return_value_type; + //! A type representing rvalue from param type. + //! On compilers without rvalue references support this type is the Boost.Moves type used for emulation. + typedef BOOST_RV_REF(value_type) rvalue_type; private: + + // TODO: move to Boost.Move + /*! \cond */ + template + static inline typename boost::conditional< + ((boost::is_nothrow_move_constructible::value && boost::is_nothrow_move_assignable::value) || !boost::is_copy_constructible::value) +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + && has_move_emulation_enabled::value +#endif + , + rvalue_type, + param_value_type + >::type move_if_noexcept(ValT& value) BOOST_NOEXCEPT { + return boost::move(value); + } + /*! \endcond */ + // Member variables //! The internal buffer used for storing elements in the circular buffer. @@ -202,7 +243,7 @@ public: Constant (in the size of the circular_buffer). \sa get_allocator() for obtaining an allocator %reference. */ - allocator_type get_allocator() const { return m_alloc; } + allocator_type get_allocator() const BOOST_NOEXCEPT { return m_alloc; } //! Get the allocator reference. /*! @@ -218,7 +259,7 @@ public: although use of stateful allocators in STL is discouraged. \sa get_allocator() const */ - allocator_type& get_allocator() { return m_alloc; } + allocator_type& get_allocator() BOOST_NOEXCEPT { return m_alloc; } // Element access @@ -236,7 +277,7 @@ public: Constant (in the size of the circular_buffer). \sa end(), rbegin(), rend() */ - iterator begin() { return iterator(this, empty() ? 0 : m_first); } + iterator begin() BOOST_NOEXCEPT { return iterator(this, empty() ? 0 : m_first); } //! Get the iterator pointing to the end of the circular_buffer. /*! @@ -252,7 +293,7 @@ public: Constant (in the size of the circular_buffer). \sa begin(), rbegin(), rend() */ - iterator end() { return iterator(this, 0); } + iterator end() BOOST_NOEXCEPT { return iterator(this, 0); } //! Get the const iterator pointing to the beginning of the circular_buffer. /*! @@ -268,7 +309,7 @@ public: Constant (in the size of the circular_buffer). \sa end() const, rbegin() const, rend() const */ - const_iterator begin() const { return const_iterator(this, empty() ? 0 : m_first); } + const_iterator begin() const BOOST_NOEXCEPT { return const_iterator(this, empty() ? 0 : m_first); } //! Get the const iterator pointing to the end of the circular_buffer. /*! @@ -284,7 +325,7 @@ public: Constant (in the size of the circular_buffer). \sa begin() const, rbegin() const, rend() const */ - const_iterator end() const { return const_iterator(this, 0); } + const_iterator end() const BOOST_NOEXCEPT { return const_iterator(this, 0); } //! Get the iterator pointing to the beginning of the "reversed" circular_buffer. /*! @@ -300,7 +341,7 @@ public: Constant (in the size of the circular_buffer). \sa rend(), begin(), end() */ - reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); } //! Get the iterator pointing to the end of the "reversed" circular_buffer. /*! @@ -316,7 +357,7 @@ public: Constant (in the size of the circular_buffer). \sa rbegin(), begin(), end() */ - reverse_iterator rend() { return reverse_iterator(begin()); } + reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); } //! Get the const iterator pointing to the beginning of the "reversed" circular_buffer. /*! @@ -332,7 +373,7 @@ public: Constant (in the size of the circular_buffer). \sa rend() const, begin() const, end() const */ - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } //! Get the const iterator pointing to the end of the "reversed" circular_buffer. /*! @@ -348,7 +389,7 @@ public: Constant (in the size of the circular_buffer). \sa rbegin() const, begin() const, end() const */ - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } //! Get the element at the index position. /*! @@ -383,7 +424,7 @@ public: Constant (in the size of the circular_buffer). \sa \link at(size_type)const at() const \endlink */ - return_value_type operator [] (size_type index) const { + const_reference operator [] (size_type index) const { BOOST_CB_ASSERT(index < size()); // check for invalid index return *add(m_first, index); } @@ -421,7 +462,7 @@ public: Constant (in the size of the circular_buffer). \sa \link operator[](size_type)const operator[] const \endlink */ - return_value_type at(size_type index) const { + const_reference at(size_type index) const { check_position(index); return (*this)[index]; } @@ -475,7 +516,7 @@ public: Constant (in the size of the circular_buffer). \sa back() const */ - return_value_type front() const { + const_reference front() const { BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available) return *m_first; } @@ -493,7 +534,7 @@ public: Constant (in the size of the circular_buffer). \sa front() const */ - return_value_type back() const { + const_reference back() const { BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available) return *((m_last == m_buff ? m_end : m_last) - 1); } @@ -508,8 +549,9 @@ public: The internal representation is often not linear and the state of the internal buffer may look like this:

|e|f|g| | | |a|b|c|d|
- end ---^
- begin -------^


+ end ___^
+ begin _______^

+ where |a|b|c|d| represents the "array one", |e|f|g| represents the "array two" and | | | | is a free space.
Now consider a typical C style function for writing data into a file:

@@ -612,8 +654,7 @@ public: This method can be useful when passing the stored data into a legacy C API as an array. \post \&(*this)[0] \< \&(*this)[1] \< ... \< \&(*this)[size() - 1] \return A pointer to the beginning of the array or 0 if empty. - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operations in the Throws section do not throw anything. \par Iterator Invalidation @@ -649,12 +690,12 @@ public: break; } if (is_uninitialized(dest)) { - m_alloc.construct(dest, *src); + ::new (dest) value_type(this_type::move_if_noexcept(*src)); ++constructed; } else { - value_type tmp = *src; - replace(src, *dest); - replace(dest, tmp); + value_type tmp = this_type::move_if_noexcept(*src); + replace(src, this_type::move_if_noexcept(*dest)); + replace(dest, boost::move(tmp)); } } } @@ -689,7 +730,7 @@ public: Constant (in the size of the circular_buffer). \sa linearize(), array_one(), array_two() */ - bool is_linearized() const { return m_first < m_last || m_last == m_buff; } + bool is_linearized() const BOOST_NOEXCEPT { return m_first < m_last || m_last == m_buff; } //! Rotate elements in the circular_buffer. /*! @@ -705,8 +746,7 @@ public: val_0 == (*this)[0] \&\& val_1 == (*this)[1] \&\& ... \&\& val_m == (*this)[m - 1] \&\& val_r1 == (*this)[m + n - 1] \&\& val_r2 == (*this)[m + n - 2] \&\& ... \&\& val_rn == (*this)[m] \param new_begin The new beginning. - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + \throws See Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the circular_buffer is full or new_begin points to begin() or if the operations in the Throws section do not throw anything. @@ -729,12 +769,12 @@ public: difference_type n = new_begin - begin(); if (m < n) { for (; m > 0; --m) { - push_front(back()); + push_front(this_type::move_if_noexcept(back())); pop_back(); } } else { for (; n > 0; --n) { - push_back(front()); + push_back(this_type::move_if_noexcept(front())); pop_front(); } } @@ -756,7 +796,7 @@ public: \sa capacity(), max_size(), reserve(), \link resize() resize(size_type, const_reference)\endlink */ - size_type size() const { return m_size; } + size_type size() const BOOST_NOEXCEPT { return m_size; } /*! \brief Get the largest possible size or capacity of the circular_buffer. (It depends on allocator's %max_size()). @@ -770,7 +810,7 @@ public: Constant (in the size of the circular_buffer). \sa size(), capacity(), reserve() */ - size_type max_size() const { + size_type max_size() const BOOST_NOEXCEPT { return (std::min)(m_alloc.max_size(), (std::numeric_limits::max)()); } @@ -787,7 +827,7 @@ public: Constant (in the size of the circular_buffer). \sa full() */ - bool empty() const { return size() == 0; } + bool empty() const BOOST_NOEXCEPT { return size() == 0; } //! Is the circular_buffer full? /*! @@ -802,7 +842,7 @@ public: Constant (in the size of the circular_buffer). \sa empty() */ - bool full() const { return capacity() == size(); } + bool full() const BOOST_NOEXCEPT { return capacity() == size(); } /*! \brief Get the maximum number of elements which can be inserted into the circular_buffer without overwriting any of already stored elements. @@ -816,7 +856,7 @@ public: Constant (in the size of the circular_buffer). \sa capacity(), size(), max_size() */ - size_type reserve() const { return capacity() - size(); } + size_type reserve() const BOOST_NOEXCEPT { return capacity() - size(); } //! Get the capacity of the circular_buffer. /*! @@ -831,18 +871,20 @@ public: \sa reserve(), size(), max_size(), set_capacity(capacity_type) */ - capacity_type capacity() const { return m_end - m_buff; } + capacity_type capacity() const BOOST_NOEXCEPT { return m_end - m_buff; } //! Change the capacity of the circular_buffer. - /*! + /*! + \pre If T is a move only type, then compiler shall support noexcept modifiers + and move constructor of T must be marked with it (must not throw exceptions). \post capacity() == new_capacity \&\& size() \<= new_capacity

If the current number of elements stored in the circular_buffer is greater than the desired new capacity then number of [size() - new_capacity] last elements will be removed and the new size will be equal to new_capacity. \param new_capacity The new capacity. - \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + \throws "An allocation error" if memory is exhausted, (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Strong. \par Iterator Invalidation @@ -860,7 +902,7 @@ public: iterator b = begin(); BOOST_TRY { reset(buff, - cb_details::uninitialized_copy_with_alloc(b, b + (std::min)(new_capacity, size()), buff, m_alloc), + cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff), new_capacity); } BOOST_CATCH(...) { deallocate(buff, new_capacity); @@ -883,7 +925,7 @@ public: size. (See the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -908,7 +950,9 @@ public: } //! Change the capacity of the circular_buffer. - /*! + /*! + \pre If T is a move only type, then compiler shall support noexcept modifiers + and move constructor of T must be marked with it (must not throw exceptions). \post capacity() == new_capacity \&\& size() \<= new_capacity

If the current number of elements stored in the circular_buffer is greater than the desired new capacity then number of [size() - new_capacity] first elements will be removed @@ -916,7 +960,7 @@ public: \param new_capacity The new capacity. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Strong. \par Iterator Invalidation @@ -933,8 +977,8 @@ public: pointer buff = allocate(new_capacity); iterator e = end(); BOOST_TRY { - reset(buff, cb_details::uninitialized_copy_with_alloc(e - (std::min)(new_capacity, size()), - e, buff, m_alloc), new_capacity); + reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()), + e, buff), new_capacity); } BOOST_CATCH(...) { deallocate(buff, new_capacity); BOOST_RETHROW @@ -956,7 +1000,7 @@ public: size. (See the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -985,8 +1029,7 @@ public: /*! \post capacity() == 0 \&\& size() == 0 \param alloc The allocator. - \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is - used). + \throws Nothing. \par Complexity Constant. \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now the constructor does not @@ -1000,7 +1043,7 @@ public: \sa circular_buffer(capacity_type, const allocator_type& alloc), set_capacity(capacity_type) */ - explicit circular_buffer(const allocator_type& alloc = allocator_type()) + explicit circular_buffer(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT : m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0), m_alloc(alloc) {} //! Create an empty circular_buffer with the specified capacity. @@ -1028,7 +1071,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the n). */ @@ -1049,7 +1092,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the n). */ @@ -1069,7 +1112,7 @@ public: \param cb The circular_buffer to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the size of cb). */ @@ -1082,7 +1125,7 @@ public: initialize_buffer(cb.capacity()); m_first = m_buff; BOOST_TRY { - m_last = cb_details::uninitialized_copy_with_alloc(cb.begin(), cb.end(), m_buff, m_alloc); + m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff); } BOOST_CATCH(...) { deallocate(m_buff, cb.capacity()); BOOST_RETHROW @@ -1091,6 +1134,22 @@ public: if (m_last == m_end) m_last = m_buff; } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! The move constructor. + /*! \brief Move constructs a circular_buffer from cb, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Constant. + */ + circular_buffer(circular_buffer&& cb) BOOST_NOEXCEPT + : m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0), m_alloc(cb.get_allocator()) { + cb.swap(*this); + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) @@ -1122,7 +1181,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the std::distance(first, last)). */ @@ -1149,7 +1208,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in std::distance(first, last); in min[capacity, std::distance(first, last)] if the InputIterator is a @@ -1175,7 +1234,7 @@ public: Constant (in the size of the circular_buffer) for scalar types; linear for other types. \sa clear() */ - ~circular_buffer() { + ~circular_buffer() BOOST_NOEXCEPT { destroy(); #if BOOST_CB_ENABLE_DEBUG invalidate_all_iterators(); @@ -1192,7 +1251,7 @@ public: \param cb The circular_buffer to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Strong. \par Iterator Invalidation @@ -1211,7 +1270,7 @@ public: return *this; pointer buff = allocate(cb.capacity()); BOOST_TRY { - reset(buff, cb_details::uninitialized_copy_with_alloc(cb.begin(), cb.end(), buff, m_alloc), cb.capacity()); + reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff), cb.capacity()); } BOOST_CATCH(...) { deallocate(buff, cb.capacity()); BOOST_RETHROW @@ -1220,6 +1279,23 @@ public: return *this; } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /*! \brief Move assigns content of cb to *this, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Complexity + Constant. + */ + circular_buffer& operator = (circular_buffer&& cb) BOOST_NOEXCEPT { + cb.swap(*this); // now `this` holds `cb` + circular_buffer(get_allocator()) // temprary that holds initial `cb` allocator + .swap(cb); // makes `cb` empty + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + //! Assign n items into the circular_buffer. /*! The content of the circular_buffer will be removed and replaced with n copies of the @@ -1230,7 +1306,7 @@ public: \param item The element the circular_buffer will be filled with. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1260,7 +1336,7 @@ public: \param item The element the circular_buffer will be filled with. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1292,7 +1368,7 @@ public: \param last The end of the range to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1329,7 +1405,7 @@ public: \param last The end of the range to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1367,7 +1443,7 @@ public: Constant (in the size of the circular_buffer). \sa swap(circular_buffer&, circular_buffer&) */ - void swap(circular_buffer& cb) { + void swap(circular_buffer& cb) BOOST_NOEXCEPT { swap_allocator(cb, is_stateless()); std::swap(m_buff, cb.m_buff); std::swap(m_end, cb.m_end); @@ -1381,7 +1457,44 @@ public: } // push and pop +private: + template + void push_back_impl(ValT item) { + if (full()) { + if (empty()) + return; + replace(m_last, static_cast(item)); + increment(m_last); + m_first = m_last; + } else { + ::new (m_last) value_type(static_cast(item)); + increment(m_last); + ++m_size; + } + } + template + void push_front_impl(ValT item) { + BOOST_TRY { + if (full()) { + if (empty()) + return; + decrement(m_first); + replace(m_first, static_cast(item)); + m_last = m_first; + } else { + decrement(m_first); + ::new (m_first) value_type(static_cast(item)); + ++m_size; + } + } BOOST_CATCH(...) { + increment(m_first); + BOOST_RETHROW + } + BOOST_CATCH_END + } + +public: //! Insert a new element at the end of the circular_buffer. /*! \post if capacity() > 0 then back() == item
@@ -1389,7 +1502,7 @@ public: 0, nothing will be inserted. \param item The element to be inserted. \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1399,18 +1512,51 @@ public: \sa \link push_front() push_front(const_reference)\endlink, pop_back(), pop_front() */ - void push_back(param_value_type item = value_type()) { - if (full()) { - if (empty()) - return; - replace(m_last, item); - increment(m_last); - m_first = m_last; - } else { - m_alloc.construct(m_last, item); - increment(m_last); - ++m_size; - } + void push_back(param_value_type item) { + push_back_impl(item); + } + + //! Insert a new element at the end of the circular_buffer using rvalue references or rvalues references emulation. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_back(rvalue_type item) { + push_back_impl(boost::move(item)); + } + + //! Insert a new default-constructed element at the end of the circular_buffer. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_back() { + value_type temp; + push_back(boost::move(temp)); } //! Insert a new element at the beginning of the circular_buffer. @@ -1420,7 +1566,7 @@ public: 0, nothing will be inserted. \param item The element to be inserted. \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1430,24 +1576,51 @@ public: \sa \link push_back() push_back(const_reference)\endlink, pop_back(), pop_front() */ - void push_front(param_value_type item = value_type()) { - BOOST_TRY { - if (full()) { - if (empty()) - return; - decrement(m_first); - replace(m_first, item); - m_last = m_first; - } else { - decrement(m_first); - m_alloc.construct(m_first, item); - ++m_size; - } - } BOOST_CATCH(...) { - increment(m_first); - BOOST_RETHROW - } - BOOST_CATCH_END + void push_front(param_value_type item) { + push_front_impl(item); + } + + //! Insert a new element at the beginning of the circular_buffer using rvalue references or rvalues references emulation. + /*! + \post if capacity() > 0 then front() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_front(rvalue_type item) { + push_front_impl(boost::move(item)); + } + + //! Insert a new default-constructed element at the beginning of the circular_buffer. + /*! + \post if capacity() > 0 then front() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), pop_front() + */ + void push_front() { + value_type temp; + push_front(boost::move(temp)); } //! Remove the last element from the circular_buffer. @@ -1491,6 +1664,15 @@ public: increment(m_first); --m_size; } +private: + template + iterator insert_impl(iterator pos, ValT item) { + BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator + iterator b = begin(); + if (full() && pos == b) + return b; + return insert_item(pos, static_cast(item)); + } public: // Insert @@ -1507,7 +1689,9 @@ public: \return Iterator to the inserted element or begin() if the item is not inserted. (See the Effect.) \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1524,12 +1708,77 @@ public: rinsert(iterator, size_type, value_type)\endlink, rinsert(iterator, InputIterator, InputIterator) */ - iterator insert(iterator pos, param_value_type item = value_type()) { - BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator - iterator b = begin(); - if (full() && pos == b) - return b; - return insert_item(pos, item); + iterator insert(iterator pos, param_value_type item) { + return insert_impl(pos, item); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted at the position pos.
+ If the circular_buffer is full, the first element will be overwritten. If the + circular_buffer is full and the pos points to begin(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(pos, end())). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, rvalue_type item) { + return insert_impl(pos, boost::move(item)); + } + + //! Insert a default-constructed element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted at the position pos.
+ If the circular_buffer is full, the first element will be overwritten. If the + circular_buffer is full and the pos points to begin(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position where the item will be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements at the insertion point (including pos) and + iterators behind the insertion point (towards the end; except iterators equal to end()). It + also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(pos, end())). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos) { + value_type temp; + return insert(pos, boost::move(temp)); } //! Insert n copies of the item at the specified position. @@ -1543,7 +1792,8 @@ public: \param n The number of items the to be inserted. \param item The element whose copies will be inserted. \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operations in the Throws section do not throw anything. \par Iterator Invalidation @@ -1556,7 +1806,7 @@ public: Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting 5 elements at the position p:

+ p ___^

After inserting 5 elements at the position p:

insert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements 1 and 2 are overwritten. This is due to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like this:

|0|0|0|0|3|4|
@@ -1594,8 +1844,10 @@ public: \param pos An iterator specifying the position where the range will be inserted. \param first The beginning of the range to be inserted. \param last The end of the range to be inserted. - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + \throws Whatever T::T(const T&) throws if the InputIterator is not a move iterator. + Whatever T::operator = (const T&) throws if the InputIterator is not a move iterator. + Whatever T::T(T&&) throws if the InputIterator is a move iterator. + Whatever T::operator = (T&&) throws if the InputIterator is a move iterator. \par Exception Safety Basic; no-throw if the operations in the Throws section do not throw anything. \par Iterator Invalidation @@ -1611,7 +1863,7 @@ public: Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting a range of elements at the position p:

+ p ___^

After inserting a range of elements at the position p:

int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

actually only elements 6, 7, 8 and 9 from the specified range get inserted and elements 1 and 2 are overwritten. This is due @@ -1631,42 +1883,16 @@ public: insert(pos, first, last, is_integral()); } - //! Insert an element before the specified position. - /*! - \pre pos is a valid iterator pointing to the circular_buffer or its end. - \post The item will be inserted before the position pos.
- If the circular_buffer is full, the last element will be overwritten. If the - circular_buffer is full and the pos points to end(), then the - item will not be inserted. If the capacity is 0, nothing will be inserted. - \param pos An iterator specifying the position before which the item will be inserted. - \param item The element to be inserted. - \return Iterator to the inserted element or end() if the item is not inserted. (See - the Effect.) - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. - \par Exception Safety - Basic; no-throw if the operations in the Throws section do not throw anything. - \par Iterator Invalidation - Invalidates iterators pointing to the elements before the insertion point (towards the beginning and - excluding pos). It also invalidates iterators pointing to the overwritten element. - \par Complexity - Linear (in std::distance(begin(), pos)). - \sa \link rinsert(iterator, size_type, param_value_type) - rinsert(iterator, size_type, value_type)\endlink, - rinsert(iterator, InputIterator, InputIterator), - \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, - \link insert(iterator, size_type, param_value_type) - insert(iterator, size_type, value_type)\endlink, - insert(iterator, InputIterator, InputIterator) - */ - iterator rinsert(iterator pos, param_value_type item = value_type()) { +private: + template + iterator rinsert_impl(iterator pos, ValT item) { BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator if (full() && pos.m_it == 0) return end(); if (pos == begin()) { BOOST_TRY { decrement(m_first); - construct_or_replace(!full(), m_first, item); + construct_or_replace(!full(), m_first, static_cast(item)); } BOOST_CATCH(...) { increment(m_first); BOOST_RETHROW @@ -1681,13 +1907,13 @@ public: bool construct = !full(); BOOST_TRY { while (src != pos.m_it) { - construct_or_replace(construct, dest, *src); + construct_or_replace(construct, dest, this_type::move_if_noexcept(*src)); increment(src); increment(dest); construct = false; } decrement(pos.m_it); - replace(pos.m_it, item); + replace(pos.m_it, static_cast(item)); } BOOST_CATCH(...) { if (!construct && !full()) { decrement(m_first); @@ -1705,6 +1931,108 @@ public: return iterator(this, pos.m_it); } +public: + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, param_value_type item) { + return rinsert_impl(pos, item); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, rvalue_type item) { + return rinsert_impl(pos, boost::move(item)); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer or its end. + \post The item will be inserted before the position pos.
+ If the circular_buffer is full, the last element will be overwritten. If the + circular_buffer is full and the pos points to end(), then the + item will not be inserted. If the capacity is 0, nothing will be inserted. + \param pos An iterator specifying the position before which the item will be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws Whatever T::T() throws. + Whatever T::T(T&&) throws. + Whatever T::operator = (T&&) throws. + Exceptions of move_if_noexcept(T&). + \par Exception Safety + Basic; no-throw if the operations in the Throws section do not throw anything. + \par Iterator Invalidation + Invalidates iterators pointing to the elements before the insertion point (towards the beginning and + excluding pos). It also invalidates iterators pointing to the overwritten element. + \par Complexity + Linear (in std::distance(begin(), pos)). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos) { + value_type temp; + return rinsert(pos, boost::move(temp)); + } + //! Insert n copies of the item before the specified position. /*! \pre pos is a valid iterator pointing to the circular_buffer or its end. @@ -1716,7 +2044,8 @@ public: \param n The number of items the to be inserted. \param item The element whose copies will be inserted. \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws. + Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operations in the Throws section do not throw anything. \par Iterator Invalidation @@ -1728,7 +2057,7 @@ public: Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting 5 elements before the position p:

+ p ___^

After inserting 5 elements before the position p:

rinsert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements 3 and 4 are overwritten. This is due to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like this:

|1|2|0|0|0|0|
@@ -1759,8 +2088,10 @@ public: \param pos An iterator specifying the position where the range will be inserted. \param first The beginning of the range to be inserted. \param last The end of the range to be inserted. - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + \throws Whatever T::T(const T&) throws if the InputIterator is not a move iterator. + Whatever T::operator = (const T&) throws if the InputIterator is not a move iterator. + Whatever T::T(T&&) throws if the InputIterator is a move iterator. + Whatever T::operator = (T&&) throws if the InputIterator is a move iterator. \par Exception Safety Basic; no-throw if the operations in the Throws section do not throw anything. \par Iterator Invalidation @@ -1775,7 +2106,7 @@ public: Consider a circular_buffer with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting a range of elements before the position p:

+ p ___^

After inserting a range of elements before the position p:

int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

actually only elements 5, 6, 7 and 8 from the specified range get inserted and elements 3 and 4 are overwritten. This is due @@ -1805,7 +2136,7 @@ public: \param pos An iterator pointing at the element to be removed. \return Iterator to the first element remaining beyond the removed element or end() if no such element exists. - \throws Whatever T::operator = (const T&) throws. + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1823,7 +2154,7 @@ public: pointer next = pos.m_it; increment(next); for (pointer p = pos.m_it; next != m_last; p = next, increment(next)) - replace(p, *next); + replace(p, this_type::move_if_noexcept(*next)); decrement(m_last); destroy_item(m_last); --m_size; @@ -1843,7 +2174,7 @@ public: \param last The end of the range to be removed. \return Iterator to the first element remaining beyond the removed elements or end() if no such element exists. - \throws Whatever T::operator = (const T&) throws. + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1862,7 +2193,7 @@ public: return first; pointer p = first.m_it; while (last.m_it != 0) - replace((first++).m_it, *last++); + replace((first++).m_it, this_type::move_if_noexcept(*last++)); do { decrement(m_last); destroy_item(m_last); @@ -1879,7 +2210,7 @@ public: \param pos An iterator pointing at the element to be removed. \return Iterator to the first element remaining in front of the removed element or begin() if no such element exists. - \throws Whatever T::operator = (const T&) throws. + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1900,7 +2231,7 @@ public: pointer prev = pos.m_it; pointer p = prev; for (decrement(prev); p != m_first; p = prev, decrement(prev)) - replace(p, *prev); + replace(p, this_type::move_if_noexcept(*prev)); destroy_item(m_first); increment(m_first); --m_size; @@ -1920,7 +2251,7 @@ public: \param last The end of the range to be removed. \return Iterator to the first element remaining in front of the removed elements or begin() if no such element exists. - \throws Whatever T::operator = (const T&) throws. + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. \par Iterator Invalidation @@ -1945,7 +2276,7 @@ public: while (first.m_it != m_first) { decrement(first.m_it); decrement(p); - replace(p, *first.m_it); + replace(p, this_type::move_if_noexcept(*first.m_it)); } do { destroy_item(m_first); @@ -1963,7 +2294,7 @@ public: \pre n \<= size() \post The n elements at the beginning of the circular_buffer will be removed. \param n The number of elements to be removed. - \throws Whatever T::operator = (const T&) throws. (Does not throw anything in case of scalars.) + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. (I.e. no throw in case of scalars.) @@ -1995,7 +2326,7 @@ public: \pre n \<= size() \post The n elements at the end of the circular_buffer will be removed. \param n The number of elements to be removed. - \throws Whatever T::operator = (const T&) throws. (Does not throw anything in case of scalars.) + \throws Exceptions of move_if_noexcept(T&). \par Exception Safety Basic; no-throw if the operation in the Throws section does not throw anything. (I.e. no throw in case of scalars.) @@ -2037,7 +2368,7 @@ public: rerase(iterator), rerase(iterator, iterator), erase_begin(size_type), erase_end(size_type) */ - void clear() { + void clear() BOOST_NOEXCEPT { destroy_content(); m_size = 0; } @@ -2101,7 +2432,7 @@ private: } //! Does the pointer point to the uninitialized memory? - bool is_uninitialized(const_pointer p) const { + bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT { return p >= m_last && (m_first < m_last || p < m_first); } @@ -2113,6 +2444,14 @@ private: #endif } + //! Replace an element. + void replace(pointer pos, rvalue_type item) { + *pos = boost::move(item); +#if BOOST_CB_ENABLE_DEBUG + invalidate_iterators(iterator(this, pos)); +#endif + } + //! Construct or replace an element. /*! construct has to be set to true if and only if @@ -2120,11 +2459,23 @@ private: */ void construct_or_replace(bool construct, pointer pos, param_value_type item) { if (construct) - m_alloc.construct(pos, item); + ::new (pos) value_type(item); else replace(pos, item); } + //! Construct or replace an element. + /*! + construct has to be set to true if and only if + pos points to an uninitialized memory. + */ + void construct_or_replace(bool construct, pointer pos, rvalue_type item) { + if (construct) + ::new (pos) value_type(boost::move(item)); + else + replace(pos, boost::move(item)); + } + //! Destroy an item. void destroy_item(pointer p) { m_alloc.destroy(p); @@ -2161,7 +2512,7 @@ private: } //! Destroy content and free allocated memory. - void destroy() { + void destroy() BOOST_NOEXCEPT { destroy_content(); deallocate(m_buff, capacity()); #if BOOST_CB_ENABLE_DEBUG @@ -2216,7 +2567,7 @@ private: // for containers std::deque tmp(first, last, m_alloc); size_type distance = tmp.size(); - initialize(distance, tmp.begin(), tmp.end(), distance); + initialize(distance, boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), distance); } //! Specialized initialize method. @@ -2260,7 +2611,7 @@ private: if (buffer_capacity == 0) return; while (first != last && !full()) { - m_alloc.construct(m_last, *first++); + ::new (m_last) value_type(*first++); increment(m_last); ++m_size; } @@ -2296,7 +2647,7 @@ private: m_size = distance; } BOOST_TRY { - m_last = cb_details::uninitialized_copy_with_alloc(first, last, m_buff, m_alloc); + m_last = cb_details::uninitialized_copy(first, last, m_buff); } BOOST_CATCH(...) { deallocate(m_buff, buffer_capacity); BOOST_RETHROW @@ -2350,8 +2701,8 @@ private: std::deque tmp(first, last, m_alloc); size_type distance = tmp.size(); assign_n(distance, distance, - cb_details::assign_range::iterator, - allocator_type>(tmp.begin(), tmp.end(), m_alloc)); + cb_details::make_assign_range + (boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()))); } //! Specialized assign method. @@ -2359,7 +2710,7 @@ private: void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range size_type distance = std::distance(first, last); - assign_n(distance, distance, cb_details::assign_range(first, last, m_alloc)); + assign_n(distance, distance, cb_details::make_assign_range(first, last)); } //! Specialized assign method. @@ -2407,7 +2758,7 @@ private: distance = new_capacity; } assign_n(new_capacity, distance, - cb_details::assign_range(first, last, m_alloc)); + cb_details::make_assign_range(first, last)); } //! Helper assign method. @@ -2441,10 +2792,11 @@ private: } //! Helper insert method. - iterator insert_item(const iterator& pos, param_value_type item) { + template + iterator insert_item(const iterator& pos, ValT item) { pointer p = pos.m_it; if (p == 0) { - construct_or_replace(!full(), m_last, item); + construct_or_replace(!full(), m_last, static_cast(item)); p = m_last; } else { pointer src = m_last; @@ -2453,11 +2805,11 @@ private: BOOST_TRY { while (src != p) { decrement(src); - construct_or_replace(construct, dest, *src); + construct_or_replace(construct, dest, this_type::move_if_noexcept(*src)); decrement(dest); construct = false; } - replace(p, item); + replace(p, static_cast(item)); } BOOST_CATCH(...) { if (!construct && !full()) { increment(m_last); @@ -2497,7 +2849,7 @@ private: void insert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) { if (!full() || pos != begin()) { for (;first != last; ++pos) - pos = insert_item(pos, *first++); + pos = insert(pos, *first++); } } @@ -2529,7 +2881,7 @@ private: pointer p = m_last; BOOST_TRY { for (; ii < construct; ++ii, increment(p)) - m_alloc.construct(p, *wrapper()); + ::new (p) value_type(*wrapper()); for (;ii < n; ++ii, increment(p)) replace(p, *wrapper()); } BOOST_CATCH(...) { @@ -2623,7 +2975,7 @@ private: for (;ii > construct; --ii, increment(p)) replace(p, *wrapper()); for (; ii > 0; --ii, increment(p)) - m_alloc.construct(p, *wrapper()); + ::new (p) value_type(*wrapper()); } BOOST_CATCH(...) { size_type constructed = ii < construct ? construct - ii : 0; m_last = add(m_last, constructed); @@ -2810,7 +3162,7 @@ inline bool operator >= (const circular_buffer& lhs, const circular_bu \sa \link circular_buffer::swap(circular_buffer&) swap(circular_buffer&)\endlink */ template -inline void swap(circular_buffer& lhs, circular_buffer& rhs) { +inline void swap(circular_buffer& lhs, circular_buffer& rhs) BOOST_NOEXCEPT { lhs.swap(rhs); } diff --git a/cpp/BoostParts/boost/circular_buffer/details.hpp b/cpp/BoostParts/boost/circular_buffer/details.hpp index da25ff07..9fdb2c78 100644 --- a/cpp/BoostParts/boost/circular_buffer/details.hpp +++ b/cpp/BoostParts/boost/circular_buffer/details.hpp @@ -15,9 +15,19 @@ #include #include +#include +#include #include #include +// Silence MS /W4 warnings like C4913: +// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used" +// This might happen when previously including some boost headers that overload the coma operator. +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable:4913) +#endif + namespace boost { namespace cb_details { @@ -28,9 +38,11 @@ template void uninitialized_fill_n_with_alloc( ForwardIterator first, Diff n, const T& item, Alloc& alloc); -template -ForwardIterator uninitialized_copy_with_alloc( - InputIterator first, InputIterator last, ForwardIterator dest, Alloc& alloc); +template +ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest); + +template +ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest); /*! \struct const_traits @@ -115,21 +127,25 @@ private: \struct assign_range \brief Helper functor for assigning range of items. */ -template +template struct assign_range { - const Iterator& m_first; - const Iterator& m_last; - Alloc& m_alloc; - assign_range(const Iterator& first, const Iterator& last, Alloc& alloc) - : m_first(first), m_last(last), m_alloc(alloc) {} + Iterator m_first; + Iterator m_last; + + assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT + : m_first(first), m_last(last) {} + template void operator () (Pointer p) const { - uninitialized_copy_with_alloc(m_first, m_last, p, m_alloc); + boost::cb_details::uninitialized_copy(m_first, m_last, p); } -private: - assign_range& operator = (const assign_range&); // do not generate }; +template +inline assign_range make_assign_range(const Iterator& first, const Iterator& last) { + return assign_range(first, last); +} + /*! \class capacity_control \brief Capacity controller of the space optimized circular buffer. @@ -137,18 +153,19 @@ private: template class capacity_control { - //! The capacity of the space optimized circular buffer. + //! The capacity of the space-optimized circular buffer. Size m_capacity; - //! The lowest guaranteed capacity of the adapted circular buffer. + //! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer. Size m_min_capacity; public: //! Constructor. capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0) - : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) { - BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); // check for capacity lower than min_capacity + : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) + { // Check for capacity lower than min_capacity. + BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); } // Default copy constructor. @@ -425,26 +442,53 @@ inline typename Traits::difference_type* distance_type(const iteratorstd::uninitialized_copy with allocator. + \fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) + \brief Equivalent of std::uninitialized_copy but with explicit specification of value type. */ -template -inline ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest, - Alloc& alloc) { +template +inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) { + typedef ValueType value_type; + + // We do not use allocator.construct and allocator.destroy + // because C++03 requires to take parameter by const reference but + // Boost.move requires nonconst reference ForwardIterator next = dest; BOOST_TRY { for (; first != last; ++first, ++dest) - alloc.construct(dest, *first); + ::new (dest) value_type(*first); } BOOST_CATCH(...) { for (; next != dest; ++next) - alloc.destroy(next); + next->~value_type(); BOOST_RETHROW } BOOST_CATCH_END return dest; } +template +ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, + true_type) { + for (; first != last; ++first, ++dest) + ::new (dest) ValueType(boost::move(*first)); + return dest; +} + +template +ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, + false_type) { + return uninitialized_copy(first, last, dest); +} + +/*! + \fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) + \brief Equivalent of std::uninitialized_copy but with explicit specification of value type and moves elements if they have noexcept move constructors. +*/ +template +ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) { + typedef typename boost::is_nothrow_move_constructible::type tag_t; + return uninitialized_move_if_noexcept_impl(first, last, dest, tag_t()); +} + /*! \fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) \brief Equivalent of std::uninitialized_fill_n with allocator. @@ -467,4 +511,8 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const } // namespace boost +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + #endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) diff --git a/cpp/BoostParts/boost/circular_buffer/space_optimized.hpp b/cpp/BoostParts/boost/circular_buffer/space_optimized.hpp index 5350676c..4518c99f 100644 --- a/cpp/BoostParts/boost/circular_buffer/space_optimized.hpp +++ b/cpp/BoostParts/boost/circular_buffer/space_optimized.hpp @@ -1,6 +1,8 @@ // Implementation of the circular buffer adaptor. // Copyright (c) 2003-2008 Jan Gaspar +// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation. +// Copyright (c) 2013 Antony Polukhin // Move semantics implementation. // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -20,10 +22,9 @@ namespace boost { /*! \class circular_buffer_space_optimized - \brief Space optimized circular buffer container adaptor. - - For detailed documentation of the space_optimized_circular_buffer visit: - http://www.boost.org/libs/circular_buffer/doc/space_optimized.html + \brief Space optimized circular buffer container adaptor. + T must be a copyable class or must have an noexcept move constructor + and move assignment operator. */ template class circular_buffer_space_optimized : @@ -51,29 +52,53 @@ public: typedef typename circular_buffer::array_range array_range; typedef typename circular_buffer::const_array_range const_array_range; typedef typename circular_buffer::param_value_type param_value_type; - typedef typename circular_buffer::return_value_type return_value_type; + typedef typename circular_buffer::rvalue_type rvalue_type; + //typedef typename circular_buffer::return_value_type return_value_type; - //! Capacity controller of the space optimized circular buffer. - /*! -

-class capacity_control {
-   size_type m_capacity;
-   size_type m_min_capacity;
-public:
-   capacity_control(size_type capacity, size_type min_capacity = 0) : m_capacity(capacity), m_min_capacity(min_capacity) {};
-   size_type %capacity() const { return m_capacity; }
-   size_type min_capacity() const { return m_min_capacity; }
-   operator size_type() const { return m_capacity; }
-};

- \pre capacity >= min_capacity -

The capacity() represents the capacity of the circular_buffer_space_optimized and - the min_capacity() determines the minimal allocated size of its internal buffer.

-

The converting constructor of the capacity_control allows implicit conversion from - size_type-like types which ensures compatibility of creating an instance of the - circular_buffer_space_optimized with other STL containers. On the other hand the operator - %size_type() provides implicit conversion to the size_type which allows to treat the - capacity of the circular_buffer_space_optimized the same way as in the - circular_buffer.

+/*
 is not passed through to html or pdf. So 
is used in code section below. Ugly :-( +Ideally want a link to capacity_control, but this would require include details +and this would expose all the functions in details. +There must be a better way of doing this. +*/ + + /*! Capacity controller of the space optimized circular buffer. + + \see capacity_control in details.hpp. +

+ +class capacity_control
+{
+ size_type m_capacity; // Available capacity.
+ size_type m_min_capacity; // Minimum capacity.
+public:
+ capacity_control(size_type capacity, size_type min_capacity = 0)
+ : m_capacity(capacity), m_min_capacity(min_capacity)
+ {};
+ size_type %capacity() const { return m_capacity; }
+ size_type min_capacity() const { return m_min_capacity; }
+ operator size_type() const { return m_capacity; }
+};
+
+

+ + +

Always + capacity >= min_capacity. +

+

+ The capacity() represents the capacity + of the circular_buffer_space_optimized and + the min_capacity() determines the minimal allocated size of its internal buffer. +

+

The converting constructor of the capacity_control allows implicit conversion from + size_type-like types which ensures compatibility of creating an instance of the + circular_buffer_space_optimized with other STL containers. + + On the other hand the operator %size_type() + provides implicit conversion to the size_type which allows to treat the + capacity of the circular_buffer_space_optimized the same way as in the + circular_buffer. +

*/ typedef cb_details::capacity_control capacity_type; @@ -98,7 +123,7 @@ public: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) reference operator [] (size_type n) { return circular_buffer::operator[](n); } - return_value_type operator [] (size_type n) const { return circular_buffer::operator[](n); } + const_reference operator [] (size_type n) const { return circular_buffer::operator[](n); } #else using circular_buffer::operator[]; #endif @@ -125,7 +150,7 @@ public: Constant (in the size of the circular_buffer_space_optimized). \sa empty() */ - bool full() const { return m_capacity_ctrl == size(); } + bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); } /*! \brief Get the maximum number of elements which can be inserted into the circular_buffer_space_optimized without overwriting any of already stored elements. @@ -139,7 +164,7 @@ public: Constant (in the size of the circular_buffer_space_optimized). \sa capacity(), size(), max_size() */ - size_type reserve() const { return m_capacity_ctrl - size(); } + size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); } //! Get the capacity of the circular_buffer_space_optimized. /*! @@ -155,7 +180,7 @@ public: \sa reserve(), size(), max_size(), set_capacity(const capacity_type&) */ - const capacity_type& capacity() const { return m_capacity_ctrl; } + const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; } #if defined(BOOST_CB_TEST) @@ -164,7 +189,7 @@ public: \note This method is not intended to be used directly by the user. It is defined only for testing purposes. */ - size_type internal_capacity() const { return circular_buffer::capacity(); } + size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer::capacity(); } #endif // #if defined(BOOST_CB_TEST) @@ -178,9 +203,9 @@ public: than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as necessary but it will never drop below capacity_ctrl.min_capacity(). \param capacity_ctrl The new capacity controller. - \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + \throws "An allocation error" if memory is exhausted, (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Strong. \par Iterator Invalidation @@ -222,7 +247,7 @@ public: the requested size. (See the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -257,7 +282,7 @@ public: \param capacity_ctrl The new capacity controller. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Strong. \par Iterator Invalidation @@ -293,7 +318,7 @@ public: the requested size. (See the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -324,7 +349,7 @@ public: \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space optimized circular buffer with zero capacity. */ - explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) + explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT : circular_buffer(0, alloc) , m_capacity_ctrl(0) {} @@ -382,7 +407,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the n). */ @@ -424,7 +449,7 @@ public: \param cb The circular_buffer_space_optimized to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in the size of cb). */ @@ -432,6 +457,23 @@ public: : circular_buffer(cb.begin(), cb.end(), cb.get_allocator()) , m_capacity_ctrl(cb.m_capacity_ctrl) {} +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! The move constructor. + /*! \brief Move constructs a circular_buffer_space_optimized from cb, + leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Constant. + */ + circular_buffer_space_optimized(circular_buffer_space_optimized&& cb) BOOST_NOEXCEPT + : circular_buffer() + , m_capacity_ctrl(0) { + cb.swap(*this); + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + //! Create a full space optimized circular buffer filled with a copy of the range. /*! \pre Valid range [first, last).
@@ -446,7 +488,8 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept + and InputIterator is a move iterator. \par Complexity Linear (in the std::distance(first, last)). */ @@ -477,7 +520,7 @@ public: \param alloc The allocator. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Complexity Linear (in std::distance(first, last); in min[capacity_ctrl.%capacity(), std::distance(first, last)] if the InputIterator @@ -552,6 +595,24 @@ public: return *this; } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /*! \brief Move assigns content of cb to *this, leaving cb empty. + \pre C++ compiler with rvalue references support. + \post cb.empty() + \param cb circular_buffer to 'steal' value from. + \throws Nothing. + \par Complexity + Constant. + */ + circular_buffer_space_optimized& operator = (circular_buffer_space_optimized&& cb) BOOST_NOEXCEPT { + cb.swap(*this); // now `this` holds `cb` + circular_buffer(get_allocator()) // temprary that holds initial `cb` allocator + .swap(cb); // makes `cb` empty + return *this; + } +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES + + //! Assign n items into the space optimized circular buffer. /*! The content of the circular_buffer_space_optimized will be removed and replaced with @@ -563,7 +624,7 @@ public: \param item The element the circular_buffer_space_optimized will be filled with. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -596,7 +657,7 @@ public: \param item The element the circular_buffer_space_optimized will be filled with. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -630,7 +691,8 @@ public: \param last The end of the range to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept and + InputIterator is a move iterator. \par Exception Safety Basic. \par Iterator Invalidation @@ -670,7 +732,8 @@ public: \param last The end of the range to be copied. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept and + InputIterator is a move iterator. \par Exception Safety Basic. \par Iterator Invalidation @@ -692,7 +755,7 @@ public: circular_buffer::assign(capacity_ctrl, first, last); } - //! Swap the contents of two space optimized circular buffers. + //! Swap the contents of two space-optimized circular-buffers. /*! \post this contains elements of cb and vice versa; the capacity and the amount of allocated memory in the internal buffer of this equal to the capacity and the amount of @@ -704,14 +767,18 @@ public: \par Iterator Invalidation Invalidates all iterators of both circular_buffer_space_optimized containers. (On the other hand the iterators still point to the same elements but within another container. If you want to rely on - this feature you have to turn the Debug Support off otherwise an - assertion will report an error if such invalidated iterator is used.) + this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG, + otherwise an assertion will report an error if such invalidated iterator is used.) \par Complexity Constant (in the size of the circular_buffer_space_optimized). - \sa \link swap(circular_buffer&, circular_buffer&) - swap(circular_buffer_space_optimized&, circular_buffer_space_optimized&)\endlink + \sa swap(circular_buffer&, circular_buffer&), + swap(circular_buffer_space_optimized&, circular_buffer_space_optimized&) + + */ - void swap(circular_buffer_space_optimized& cb) { + // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103. + + void swap(circular_buffer_space_optimized& cb) BOOST_NOEXCEPT { std::swap(m_capacity_ctrl, cb.m_capacity_ctrl); circular_buffer::swap(cb); } @@ -725,7 +792,7 @@ public: \param item The element to be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -736,11 +803,60 @@ public: \sa \link push_front() push_front(const_reference)\endlink, pop_back(), pop_front() */ - void push_back(param_value_type item = value_type()) { + void push_back(param_value_type item) { check_low_capacity(); circular_buffer::push_back(item); } + //! Insert a new element at the end of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then back() == item
+ If the circular_buffer_space_optimized is full, the first element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_front() push_front(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_back(rvalue_type item) { + check_low_capacity(); + circular_buffer::push_back(boost::move(item)); + } + + //! Insert a new element at the end of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then back() == item
+ If the circular_buffer_space_optimized is full, the first element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_front() push_front(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_back() { + check_low_capacity(); + circular_buffer::push_back(); + } + //! Insert a new element at the beginning of the space optimized circular buffer. /*! \post if capacity().%capacity() > 0 then front() == item
@@ -750,7 +866,7 @@ public: \param item The element to be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. + Whatever T::T(const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -761,11 +877,61 @@ public: \sa \link push_back() push_back(const_reference)\endlink, pop_back(), pop_front() */ - void push_front(param_value_type item = value_type()) { + void push_front(param_value_type item) { check_low_capacity(); circular_buffer::push_front(item); } + //! Insert a new element at the beginning of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then front() == item
+ If the circular_buffer_space_optimized is full, the last element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param item The element to be inserted. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_back() push_back(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_front(rvalue_type item) { + check_low_capacity(); + circular_buffer::push_front(boost::move(item)); + } + + //! Insert a new element at the beginning of the space optimized circular buffer. + /*! + \post if capacity().%capacity() > 0 then front() == item
+ If the circular_buffer_space_optimized is full, the last element will be removed. If the + capacity is 0, nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link push_back() push_back(const_reference)\endlink, pop_back(), + pop_front() + */ + void push_front() { + check_low_capacity(); + circular_buffer::push_front(); + } + //! Remove the last element from the space optimized circular buffer. /*! \pre !empty() @@ -826,8 +992,8 @@ public: the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -843,12 +1009,88 @@ public: rinsert(iterator, size_type, value_type)\endlink, rinsert(iterator, InputIterator, InputIterator) */ - iterator insert(iterator pos, param_value_type item = value_type()) { + iterator insert(iterator pos, param_value_type item) { size_type index = pos - begin(); check_low_capacity(); return circular_buffer::insert(begin() + index, item); } + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted at the position pos.
+ If the circular_buffer_space_optimized is full, the first element will be overwritten. If + the circular_buffer_space_optimized is full and the pos points to + begin(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos, rvalue_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index, boost::move(item)); + } + + //! Insert an element at the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted at the position pos.
+ If the circular_buffer_space_optimized is full, the first element will be overwritten. If + the circular_buffer_space_optimized is full and the pos points to + begin(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position where the item will be inserted. + \return Iterator to the inserted element or begin() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator), + \link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink, + \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator) + */ + iterator insert(iterator pos) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::insert(begin() + index); + } + //! Insert n copies of the item at the specified position. /*! \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its @@ -863,8 +1105,8 @@ public: \param item The element whose copies will be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -876,7 +1118,7 @@ public: Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting 5 elements at the position p:

+ p ___^

After inserting 5 elements at the position p:

insert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements 1 and 2 are overwritten. This is due to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like this:

|0|0|0|0|3|4|
@@ -911,8 +1153,7 @@ public: \param last The end of the range to be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -927,7 +1168,7 @@ public: Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting a range of elements at the position p:

+ p ___^

After inserting a range of elements at the position p:

int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

actually only elements 6, 7, 8 and 9 from the specified range get inserted and elements 1 and 2 are overwritten. This is due @@ -962,8 +1203,8 @@ public: the Effect.) \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -979,12 +1220,88 @@ public: insert(iterator, size_type, value_type)\endlink, insert(iterator, InputIterator, InputIterator) */ - iterator rinsert(iterator pos, param_value_type item = value_type()) { + iterator rinsert(iterator pos, param_value_type item) { size_type index = pos - begin(); check_low_capacity(); return circular_buffer::rinsert(begin() + index, item); } + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted before the position pos.
+ If the circular_buffer_space_optimized is full, the last element will be overwritten. If the + circular_buffer_space_optimized is full and the pos points to + end(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position before which the item will be inserted. + \param item The element to be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos, rvalue_type item) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index, boost::move(item)); + } + + //! Insert an element before the specified position. + /*! + \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its + end. + \post The item will be inserted before the position pos.
+ If the circular_buffer_space_optimized is full, the last element will be overwritten. If the + circular_buffer_space_optimized is full and the pos points to + end(), then the item will not be inserted. If the capacity is 0, + nothing will be inserted.

+ The amount of allocated memory in the internal buffer may be predictively increased. + \param pos An iterator specifying the position before which the item will be inserted. + \return Iterator to the inserted element or end() if the item is not inserted. (See + the Effect.) + \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is + used). + Whatever T::T() throws. + Whatever T::T(const T&) throws or nothing if T::T(T&&) is noexcept. + \par Exception Safety + Basic. + \par Iterator Invalidation + Invalidates all iterators pointing to the circular_buffer_space_optimized (except iterators + equal to end()). + \par Complexity + Linear (in the size of the circular_buffer_space_optimized). + \sa \link rinsert(iterator, size_type, param_value_type) + rinsert(iterator, size_type, value_type)\endlink, + rinsert(iterator, InputIterator, InputIterator), + \link insert(iterator, param_value_type) insert(iterator, value_type)\endlink, + \link insert(iterator, size_type, param_value_type) + insert(iterator, size_type, value_type)\endlink, + insert(iterator, InputIterator, InputIterator) + */ + iterator rinsert(iterator pos) { + size_type index = pos - begin(); + check_low_capacity(); + return circular_buffer::rinsert(begin() + index); + } + //! Insert n copies of the item before the specified position. /*! \pre pos is a valid iterator pointing to the circular_buffer_space_optimized or its @@ -999,8 +1316,8 @@ public: \param item The element whose copies will be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1012,7 +1329,7 @@ public: Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting 5 elements before the position p:

+ p ___^

After inserting 5 elements before the position p:

rinsert(p, (size_t)5, 0);

actually only 4 elements get inserted and elements 3 and 4 are overwritten. This is due to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like this:

|1|2|0|0|0|0|
@@ -1048,8 +1365,8 @@ public: \param last The end of the range to be inserted. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::T(const T&) throws. - \throws Whatever T::operator = (const T&) throws. + Whatever T::T(const T&) throws. + Whatever T::operator = (const T&) throws. \par Exception Safety Basic. \par Iterator Invalidation @@ -1064,7 +1381,7 @@ public: Consider a circular_buffer_space_optimized with the capacity of 6 and the size of 4. Its internal buffer may look like the one below.

|1|2|3|4| | |
- p ---^

After inserting a range of elements before the position p:

+ p ___^

After inserting a range of elements before the position p:

int array[] = { 5, 6, 7, 8, 9 };
insert(p, array, array + 5);

actually only elements 5, 6, 7 and 8 from the specified range get inserted and elements 3 and 4 are overwritten. This is due @@ -1094,7 +1411,8 @@ public: element exists. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -1124,7 +1442,8 @@ public: element exists. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -1153,7 +1472,8 @@ public: such element exists. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -1162,7 +1482,7 @@ public: \par Complexity Linear (in the size of the circular_buffer_space_optimized). \note Basically there is no difference between erase(iterator) and this method. It is implemented - only for consistency with the base circular_buffer. + only for consistency with the base circular_buffer. \sa erase(iterator), erase(iterator, iterator), rerase(iterator, iterator), clear() */ @@ -1185,7 +1505,8 @@ public: such element exists. \throws "An allocation error" if memory is exhausted (std::bad_alloc if the standard allocator is used). - \throws Whatever T::operator = (const T&) throws. + Whatever T::operator = (const T&) throws or + nothing if T::operator = (T&&) is noexcept. \par Exception Safety Basic. \par Iterator Invalidation @@ -1195,7 +1516,7 @@ public: Linear (in the size of the circular_buffer_space_optimized). \note Basically there is no difference between erase(iterator, iterator) and this method. It is implemented only for consistency with the base - circular_buffer. + . \sa erase(iterator), erase(iterator, iterator), rerase(iterator), clear() */ @@ -1414,7 +1735,7 @@ inline bool operator >= (const circular_buffer_space_optimized& lhs, //! Swap the contents of two space optimized circular buffers. template inline void swap(circular_buffer_space_optimized& lhs, - circular_buffer_space_optimized& rhs) { + circular_buffer_space_optimized& rhs) BOOST_NOEXCEPT { lhs.swap(rhs); } diff --git a/cpp/BoostParts/boost/config.hpp b/cpp/BoostParts/boost/config.hpp index f37585eb..6ec3645c 100644 --- a/cpp/BoostParts/boost/config.hpp +++ b/cpp/BoostParts/boost/config.hpp @@ -1,6 +1,6 @@ // Boost config.hpp configuration header file ------------------------------// -// (C) Copyright John Maddock 2002. +// (C) Copyright John Maddock 2002. // Use, modification and distribution are subject to 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) @@ -56,15 +56,8 @@ // get config suffix code: #include +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + #endif // BOOST_CONFIG_HPP - - - - - - - - - - - diff --git a/cpp/BoostParts/boost/config/auto_link.hpp b/cpp/BoostParts/boost/config/auto_link.hpp index e36d06a0..13cbad43 100644 --- a/cpp/BoostParts/boost/config/auto_link.hpp +++ b/cpp/BoostParts/boost/config/auto_link.hpp @@ -151,11 +151,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. // vc10: # define BOOST_LIB_TOOLSET "vc100" -# elif defined(BOOST_MSVC) +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) // vc11: # define BOOST_LIB_TOOLSET "vc110" +# elif defined(BOOST_MSVC) + + // vc12: +# define BOOST_LIB_TOOLSET "vc120" + # elif defined(__BORLANDC__) // CBuilder 6: @@ -421,3 +426,4 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. # undef BOOST_DYN_LINK #endif + diff --git a/cpp/BoostParts/boost/config/compiler/borland.hpp b/cpp/BoostParts/boost/config/compiler/borland.hpp index 38ac4a9a..a8f5baae 100644 --- a/cpp/BoostParts/boost/config/compiler/borland.hpp +++ b/cpp/BoostParts/boost/config/compiler/borland.hpp @@ -155,7 +155,7 @@ # define BOOST_NO_CXX11_DECLTYPE # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_EXTERN_TEMPLATE -# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_CXX11_STATIC_ASSERT #else @@ -191,6 +191,9 @@ #define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES #if __BORLANDC__ >= 0x590 # define BOOST_HAS_TR1_HASH @@ -243,7 +246,7 @@ // all versions support __declspec: // #if defined(__STRICT_ANSI__) -// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif // @@ -282,7 +285,3 @@ #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) - - - - diff --git a/cpp/BoostParts/boost/config/compiler/clang.hpp b/cpp/BoostParts/boost/config/compiler/clang.hpp index 8e38821b..b57e26c5 100644 --- a/cpp/BoostParts/boost/config/compiler/clang.hpp +++ b/cpp/BoostParts/boost/config/compiler/clang.hpp @@ -1,13 +1,15 @@ // (C) Copyright Douglas Gregor 2010 // -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. // Clang compiler setup. +#define BOOST_HAS_PRAGMA_ONCE + #if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) # define BOOST_NO_EXCEPTIONS #endif @@ -26,6 +28,14 @@ #define BOOST_HAS_NRVO +// Branch prediction hints +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + // Clang supports "long long" in all compilation modes. #define BOOST_HAS_LONG_LONG @@ -38,15 +48,15 @@ # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #endif -// -// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through -// between switch labels. -// -#if __cplusplus >= 201103L && defined(__has_warning) -# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") -# define BOOST_FALLTHROUGH [[clang::fallthrough]] -# endif -#endif +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif #if !__has_feature(cxx_auto_type) # define BOOST_NO_CXX11_AUTO_DECLARATIONS @@ -146,6 +156,18 @@ # define BOOST_NO_CXX11_USER_DEFINED_LITERALS #endif +#if !(__has_feature(cxx_alignas) || __has_extension(cxx_alignas)) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + // Clang always supports variadic macros // Clang always supports extern templates diff --git a/cpp/BoostParts/boost/config/compiler/codegear.hpp b/cpp/BoostParts/boost/config/compiler/codegear.hpp index 9dd97bc0..00e0bb94 100644 --- a/cpp/BoostParts/boost/config/compiler/codegear.hpp +++ b/cpp/BoostParts/boost/config/compiler/codegear.hpp @@ -72,6 +72,12 @@ # endif #endif + +// Reportedly, #pragma once is supported since C++ Builder 2010 +#if (__CODEGEARC__ >= 0x620) +# define BOOST_HAS_PRAGMA_ONCE +#endif + // // C++0x macros: // @@ -111,6 +117,9 @@ #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES // // TR1 macros: @@ -151,7 +160,7 @@ // all versions support __declspec: // #if defined(__STRICT_ANSI__) -// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif // diff --git a/cpp/BoostParts/boost/config/compiler/common_edg.hpp b/cpp/BoostParts/boost/config/compiler/common_edg.hpp index 4b5d2d26..70e7efa2 100644 --- a/cpp/BoostParts/boost/config/compiler/common_edg.hpp +++ b/cpp/BoostParts/boost/config/compiler/common_edg.hpp @@ -1,10 +1,10 @@ -// (C) Copyright John Maddock 2001 - 2002. -// (C) Copyright Jens Maurer 2001. -// (C) Copyright David Abrahams 2002. -// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. // (C) Copyright Markus Schoepflin 2005. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -33,15 +33,15 @@ #if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) # define BOOST_NO_TEMPLATE_TEMPLATES -#endif +#endif #if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) # define BOOST_NO_IS_ABSTRACT -#endif +#endif #if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL -#endif +#endif // See also kai.hpp which checks a Kai-specific symbol for EH # if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) @@ -54,6 +54,11 @@ # define BOOST_NO_LONG_LONG # endif +// Not sure what version was the first to support #pragma once, but +// different EDG-based compilers (e.g. Intel) supported it for ages. +// Add a proper version check if it causes problems. +#define BOOST_HAS_PRAGMA_ONCE + // // C++0x features // @@ -96,6 +101,9 @@ #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES #ifdef c_plusplus // EDG has "long long" in non-strict mode diff --git a/cpp/BoostParts/boost/config/compiler/cray.hpp b/cpp/BoostParts/boost/config/compiler/cray.hpp index 4455c5c4..3ce29f01 100644 --- a/cpp/BoostParts/boost/config/compiler/cray.hpp +++ b/cpp/BoostParts/boost/config/compiler/cray.hpp @@ -55,10 +55,11 @@ #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_ALIGNAS //#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG #define BOOST_MATH_DISABLE_STD_FPCLASSIFY //#define BOOST_HAS_FPCLASSIFY -#define BOOST_SP_USE_PTHREADS -#define BOOST_AC_USE_PTHREADS +#define BOOST_SP_USE_PTHREADS +#define BOOST_AC_USE_PTHREADS diff --git a/cpp/BoostParts/boost/config/compiler/digitalmars.hpp b/cpp/BoostParts/boost/config/compiler/digitalmars.hpp index 0206dc38..7de6adb1 100644 --- a/cpp/BoostParts/boost/config/compiler/digitalmars.hpp +++ b/cpp/BoostParts/boost/config/compiler/digitalmars.hpp @@ -1,8 +1,8 @@ // Copyright (C) Christof Meerwald 2003 // Copyright (C) Dan Watkins 2003 // -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// Use, modification and distribution are subject to 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) // Digital Mars C++ compiler setup: @@ -11,15 +11,7 @@ #define BOOST_HAS_LONG_LONG #define BOOST_HAS_PRAGMA_ONCE -#if (__DMC__ <= 0x833) -#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL -#define BOOST_NO_TEMPLATE_TEMPLATES -#define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING -#define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS -#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -#endif -#if (__DMC__ <= 0x840) || !defined(BOOST_STRICT_CONFIG) -#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +#if !defined(BOOST_STRICT_CONFIG) #define BOOST_NO_MEMBER_TEMPLATE_FRIENDS #define BOOST_NO_OPERATORS_IN_NAMESPACE #define BOOST_NO_UNREACHABLE_RETURN_DETECTION @@ -30,11 +22,9 @@ // // has macros: -#if (__DMC__ >= 0x840) #define BOOST_HAS_DIRENT_H #define BOOST_HAS_STDINT_H #define BOOST_HAS_WINTHREADS -#endif #if (__DMC__ >= 0x847) #define BOOST_HAS_EXPM1 @@ -87,12 +77,11 @@ #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES -#if (__DMC__ < 0x812) -#define BOOST_NO_CXX11_VARIADIC_MACROS -#endif - -#if __DMC__ < 0x800 +#if (__DMC__ <= 0x840) #error "Compiler not supported or configured - please reconfigure" #endif // diff --git a/cpp/BoostParts/boost/config/compiler/gcc.hpp b/cpp/BoostParts/boost/config/compiler/gcc.hpp index b3d12ec6..aa628e5a 100644 --- a/cpp/BoostParts/boost/config/compiler/gcc.hpp +++ b/cpp/BoostParts/boost/config/compiler/gcc.hpp @@ -1,12 +1,12 @@ -// (C) Copyright John Maddock 2001 - 2003. -// (C) Copyright Darin Adler 2001 - 2002. -// (C) Copyright Jens Maurer 2001 - 2002. -// (C) Copyright Beman Dawes 2001 - 2003. -// (C) Copyright Douglas Gregor 2002. -// (C) Copyright David Abrahams 2002 - 2003. -// (C) Copyright Synge Todo 2003. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -20,51 +20,12 @@ #define BOOST_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif -#if __GNUC__ < 3 -# if __GNUC_MINOR__ == 91 - // egcs 1.1 won't parse shared_ptr.hpp without this: -# define BOOST_NO_AUTO_PTR -# endif -# if __GNUC_MINOR__ < 95 - // - // Prior to gcc 2.95 member templates only partly - // work - define BOOST_MSVC6_MEMBER_TEMPLATES - // instead since inline member templates mostly work. - // -# define BOOST_NO_MEMBER_TEMPLATES -# if __GNUC_MINOR__ >= 9 -# define BOOST_MSVC6_MEMBER_TEMPLATES -# endif -# endif - -# if __GNUC_MINOR__ < 96 -# define BOOST_NO_SFINAE -# endif - -# if __GNUC_MINOR__ <= 97 -# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS -# define BOOST_NO_OPERATORS_IN_NAMESPACE -# endif - -# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE -# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL -# define BOOST_NO_IS_ABSTRACT -# define BOOST_NO_CXX11_EXTERN_TEMPLATE -// Variadic macros do not exist for gcc versions before 3.0 -# define BOOST_NO_CXX11_VARIADIC_MACROS -#elif __GNUC__ == 3 +#if __GNUC__ == 3 # if defined (__PATHSCALE__) # define BOOST_NO_TWO_PHASE_NAME_LOOKUP # define BOOST_NO_IS_ABSTRACT # endif - // - // gcc-3.x problems: - // - // Bug specific to gcc 3.1 and 3.2: - // -# if ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2)) -# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -# endif + # if __GNUC_MINOR__ < 4 # define BOOST_NO_IS_ABSTRACT # endif @@ -80,6 +41,11 @@ # endif #endif +// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define BOOST_HAS_PRAGMA_ONCE +#endif + #if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 ) // Previous versions of GCC did not completely implement value-initialization: // GCC Bug 30111, "Value-initialization of POD base class doesn't initialize @@ -104,7 +70,7 @@ // #if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) # define BOOST_HAS_THREADS -#endif +#endif // // gcc has "long long" @@ -114,28 +80,30 @@ // // gcc implements the named return value optimization since version 3.1 // -#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) #define BOOST_HAS_NRVO -#endif + +// Branch prediction hints +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) // // Dynamic shared object (DSO) and dynamic-link library (DLL) support // #if __GNUC__ >= 4 # if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__) - // All Win32 development environments, including 64-bit Windows and MinGW, define + // All Win32 development environments, including 64-bit Windows and MinGW, define // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, // so does not define _WIN32 or its variants. # define BOOST_HAS_DECLSPEC -# define BOOST_SYMBOL_EXPORT __attribute__((dllexport)) -# define BOOST_SYMBOL_IMPORT __attribute__((dllimport)) +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) # else -# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) # define BOOST_SYMBOL_IMPORT # endif -# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #else -// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined # define BOOST_SYMBOL_EXPORT #endif @@ -158,7 +126,7 @@ // // We disable this if the compiler is really nvcc as it // doesn't actually support __int128 as of CUDA_VERSION=5000 -// even though it defines __SIZEOF_INT128__. +// even though it defines __SIZEOF_INT128__. // See https://svn.boost.org/trac/boost/ticket/8048 // Only re-enable this for nvcc if you're absolutely sure // of the circumstances under which it's supported: @@ -183,7 +151,7 @@ # define BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_NO_CXX11_STATIC_ASSERT -// Variadic templates compiler: +// Variadic templates compiler: // http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html # if defined(__VARIADIC_TEMPLATES) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4) && defined(__GXX_EXPERIMENTAL_CXX0X__)) # define BOOST_HAS_VARIADIC_TMPL @@ -202,12 +170,19 @@ # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES #endif #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) # define BOOST_NO_SFINAE_EXPR #endif +// GCC 4.5 forbids declaration of defaulted functions in private or protected sections +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + // C++0x features in 4.5.0 and later // #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__) @@ -243,6 +218,12 @@ # define BOOST_NO_CXX11_USER_DEFINED_LITERALS #endif +// C++0x features in 4.8.n and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_CXX11_ALIGNAS +#endif + // C++0x features in 4.8.1 and later // #if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40801) || !defined(__GXX_EXPERIMENTAL_CXX0X__) @@ -261,8 +242,8 @@ #endif // versions check: -// we don't know gcc prior to version 2.90: -#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 90) +// we don't know gcc prior to version 3.30: +#if (__GNUC__ < 3) || (__GNUC__ == 3 && (__GNUC_MINOR__ < 3)) # error "Compiler not configured - please reconfigure" #endif // diff --git a/cpp/BoostParts/boost/config/compiler/gcc_xml.hpp b/cpp/BoostParts/boost/config/compiler/gcc_xml.hpp index 1af2fc1a..d2e0c74f 100644 --- a/cpp/BoostParts/boost/config/compiler/gcc_xml.hpp +++ b/cpp/BoostParts/boost/config/compiler/gcc_xml.hpp @@ -1,6 +1,6 @@ -// (C) Copyright John Maddock 2006. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -18,7 +18,7 @@ // #if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) # define BOOST_HAS_THREADS -#endif +#endif // // gcc has "long long" @@ -44,7 +44,7 @@ # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST -# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_SFINAE_EXPR # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_LAMBDAS @@ -55,6 +55,9 @@ # define BOOST_NO_CXX11_NOEXCEPT # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ diff --git a/cpp/BoostParts/boost/config/compiler/hp_acc.hpp b/cpp/BoostParts/boost/config/compiler/hp_acc.hpp index 12c791b3..f08dca44 100644 --- a/cpp/BoostParts/boost/config/compiler/hp_acc.hpp +++ b/cpp/BoostParts/boost/config/compiler/hp_acc.hpp @@ -1,11 +1,11 @@ -// (C) Copyright John Maddock 2001 - 2003. -// (C) Copyright Jens Maurer 2001 - 2003. -// (C) Copyright Aleksey Gurtovoy 2002. -// (C) Copyright David Abrahams 2002 - 2003. -// (C) Copyright Toon Knapen 2003. +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. // (C) Copyright Boris Gubenko 2006 - 2007. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -43,7 +43,7 @@ # define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS # define BOOST_NO_IS_ABSTRACT # define BOOST_NO_MEMBER_TEMPLATE_FRIENDS -#endif +#endif // optional features rather than defects: #if (__HP_aCC >= 33900) @@ -119,8 +119,11 @@ #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES -/* +/* See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 */ diff --git a/cpp/BoostParts/boost/config/compiler/intel.hpp b/cpp/BoostParts/boost/config/compiler/intel.hpp index e94540a5..3f0eaa18 100644 --- a/cpp/BoostParts/boost/config/compiler/intel.hpp +++ b/cpp/BoostParts/boost/config/compiler/intel.hpp @@ -27,7 +27,7 @@ #endif // Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' -#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) # define BOOST_INTEL_STDCXX0X #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) @@ -47,11 +47,6 @@ # define BOOST_INTEL_LINUX BOOST_INTEL #endif -#if (BOOST_INTEL_CXX_VERSION <= 500) && defined(_MSC_VER) -# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -# define BOOST_NO_TEMPLATE_TEMPLATES -#endif - #if (BOOST_INTEL_CXX_VERSION <= 600) # if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) @@ -111,7 +106,7 @@ # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # endif #endif -#if (defined(__GNUC__) && (__GNUC__ < 4)) || defined(_WIN32) || (BOOST_INTEL_CXX_VERSION <= 1200) +#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200) // GCC or VC emulation: #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #endif @@ -154,10 +149,18 @@ template<> struct assert_intrinsic_wchar_t {}; # define BOOST_HAS_NRVO #endif +// Branch prediction hints +// I'm not sure 8.0 was the first version to support these builtins, +// update the condition if the version is not accurate. (Andrey Semashev) +#if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800 +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif + // // versions check: -// we don't support Intel prior to version 5.0: -#if BOOST_INTEL_CXX_VERSION < 500 +// we don't support Intel prior to version 6.0: +#if BOOST_INTEL_CXX_VERSION < 600 # error "Compiler not supported or configured - please reconfigure" #endif @@ -173,10 +176,10 @@ template<> struct assert_intrinsic_wchar_t {}; // // An attempt to value-initialize a pointer-to-member may trigger an -// internal error on Intel <= 11.1 (last checked version), as was +// internal error on Intel <= 11.1 (last checked version), as was // reported by John Maddock, Intel support issue 589832, May 2010. // Moreover, according to test results from Huang-Vista-x86_32_intel, -// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some +// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some // cases when it should be value-initialized. // (Niels Dekker, LKEB, May 2010) // Apparently Intel 12.1 (compiler version number 9999 !!) has the same issue (compiler regression). @@ -221,10 +224,11 @@ template<> struct assert_intrinsic_wchar_t {}; # undef BOOST_NO_CXX11_DECLTYPE # undef BOOST_NO_CXX11_AUTO_DECLARATIONS # undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES #endif // icl Version 12.1.0.233 Build 20110811 and possibly some other builds -// had an incorrect __INTEL_COMPILER value of 9999. Intel say this has been fixed. +// had an incorrect __INTEL_COMPILER value of 9999. Intel say this has been fixed. #if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION > 1200) # undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # undef BOOST_NO_CXX11_NULLPTR @@ -234,8 +238,44 @@ template<> struct assert_intrinsic_wchar_t {}; # undef BOOST_NO_CXX11_VARIADIC_TEMPLATES // http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ -// continues to list scoped enum support as "Partial" -//# undef BOOST_NO_CXX11_SCOPED_ENUMS +// continues to list scoped enum support as "Partial" +//# undef BOOST_NO_CXX11_SCOPED_ENUMS +#endif +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(_MSC_VER) +# undef BOOST_NO_CXX11_INLINE_NAMESPACES +# undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +// This one generates internal compiler errors in multiprecision, disabled for now: +//# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +// This one generates errors when used with conditional exception specifications, for example in multiprecision: +//# undef BOOST_NO_CXX11_NOEXCEPT +# undef BOOST_NO_CXX11_RANGE_BASED_FOR +# undef BOOST_NO_CXX11_SCOPED_ENUMS +# undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif +#if (BOOST_INTEL_CXX_VERSION >= 1310) +# undef BOOST_NO_SFINAE_EXPR +#endif +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION >= 1400) && !defined(_MSC_VER) +# undef BOOST_NO_CXX11_UNICODE_LITERALS +# undef BOOST_NO_CXX11_RAW_LITERALS +// This one generates errors when used with conditional exception specifications, for example in multiprecision: +//# undef BOOST_NO_CXX11_NOEXCEPT +// This breaks multiprecision: +//# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# undef BOOST_NO_CXX11_HDR_THREAD +# undef BOOST_NO_CXX11_CHAR32_T +# undef BOOST_NO_CXX11_CHAR16_T +#endif + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400) +// A regression in Intel's compiler means that seems to be broken in this release as well as : +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_TUPLE #endif #if defined(_MSC_VER) && (_MSC_VER <= 1700) @@ -247,6 +287,9 @@ template<> struct assert_intrinsic_wchar_t {}; # define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_TEMPLATE_ALIASES +# if(BOOST_INTEL_CXX_VERSION < 1310) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# endif #endif #if (BOOST_INTEL_CXX_VERSION < 1200) @@ -256,9 +299,17 @@ template<> struct assert_intrinsic_wchar_t {}; # define BOOST_NO_FENV_H #endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_HAS_STDINT_H +#endif + +#if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310) +# define BOOST_HAS_INT128 +#endif + // // last known and checked version: -#if (BOOST_INTEL_CXX_VERSION > 1200) +#if (BOOST_INTEL_CXX_VERSION > 1310) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # elif defined(_MSC_VER) diff --git a/cpp/BoostParts/boost/config/compiler/metrowerks.hpp b/cpp/BoostParts/boost/config/compiler/metrowerks.hpp index 4ca8af8a..e1727860 100644 --- a/cpp/BoostParts/boost/config/compiler/metrowerks.hpp +++ b/cpp/BoostParts/boost/config/compiler/metrowerks.hpp @@ -1,11 +1,11 @@ -// (C) Copyright John Maddock 2001. -// (C) Copyright Darin Adler 2001. -// (C) Copyright Peter Dimov 2001. -// (C) Copyright David Abrahams 2001 - 2002. -// (C) Copyright Beman Dawes 2001 - 2003. -// (C) Copyright Stefan Slapeta 2004. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -15,7 +15,7 @@ // locale support is disabled when linking with the dynamic runtime # ifdef _MSL_NO_LOCALE # define BOOST_NO_STD_LOCALE -# endif +# endif # if __MWERKS__ <= 0x2301 // 5.3 # define BOOST_NO_FUNCTION_TEMPLATE_ORDERING @@ -90,7 +90,7 @@ #if __MWERKS__ > 0x3206 && __option(rvalue_refs) # define BOOST_HAS_RVALUE_REFS #else -# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RVALUE_REFERENCES #endif #define BOOST_NO_CXX11_AUTO_DECLARATIONS #define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS @@ -120,6 +120,9 @@ #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES #define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) diff --git a/cpp/BoostParts/boost/config/compiler/mpw.hpp b/cpp/BoostParts/boost/config/compiler/mpw.hpp index 7ef38efa..69104674 100644 --- a/cpp/BoostParts/boost/config/compiler/mpw.hpp +++ b/cpp/BoostParts/boost/config/compiler/mpw.hpp @@ -1,7 +1,7 @@ -// (C) Copyright John Maddock 2001 - 2002. -// (C) Copyright Aleksey Gurtovoy 2002. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -69,6 +69,9 @@ #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES // // versions check: diff --git a/cpp/BoostParts/boost/config/compiler/nvcc.hpp b/cpp/BoostParts/boost/config/compiler/nvcc.hpp index 03203fb5..bbe81f6e 100644 --- a/cpp/BoostParts/boost/config/compiler/nvcc.hpp +++ b/cpp/BoostParts/boost/config/compiler/nvcc.hpp @@ -14,15 +14,3 @@ // NVIDIA Specific support // BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device #define BOOST_GPU_ENABLED __host__ __device__ - -// Boost support macro for NVCC -// NVCC Basically behaves like some flavor of MSVC6 + some specific quirks -#ifdef __GNUC__ - -#include - -#elif defined(_MSC_VER) - -#include - -#endif diff --git a/cpp/BoostParts/boost/config/compiler/pathscale.hpp b/cpp/BoostParts/boost/config/compiler/pathscale.hpp index 07d14609..567d83cc 100644 --- a/cpp/BoostParts/boost/config/compiler/pathscale.hpp +++ b/cpp/BoostParts/boost/config/compiler/pathscale.hpp @@ -1,7 +1,7 @@ // (C) Copyright Bryce Lelbach 2011 -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -77,5 +77,7 @@ # define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES #endif - diff --git a/cpp/BoostParts/boost/config/compiler/pgi.hpp b/cpp/BoostParts/boost/config/compiler/pgi.hpp index 64c0d753..d50cbef8 100644 --- a/cpp/BoostParts/boost/config/compiler/pgi.hpp +++ b/cpp/BoostParts/boost/config/compiler/pgi.hpp @@ -41,6 +41,9 @@ #define BOOST_HAS_THREADS #define BOOST_HAS_NRVO #define BOOST_HAS_LONG_LONG +#if defined(linux) || defined(__linux) || defined(__linux__) +# define BOOST_HAS_STDINT_H +#endif // options --enable-test wants undefined #undef BOOST_NO_STDC_NAMESPACE @@ -112,6 +115,9 @@ #define BOOST_NO_CXX11_HDR_CHRONO #define BOOST_NO_CXX11_HDR_ARRAY #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES // // version check: diff --git a/cpp/BoostParts/boost/config/compiler/sunpro_cc.hpp b/cpp/BoostParts/boost/config/compiler/sunpro_cc.hpp index 88421ee4..486d5c43 100644 --- a/cpp/BoostParts/boost/config/compiler/sunpro_cc.hpp +++ b/cpp/BoostParts/boost/config/compiler/sunpro_cc.hpp @@ -1,10 +1,10 @@ -// (C) Copyright John Maddock 2001. -// (C) Copyright Jens Maurer 2001 - 2003. -// (C) Copyright Peter Dimov 2002. -// (C) Copyright Aleksey Gurtovoy 2002 - 2003. -// (C) Copyright David Abrahams 2002. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 2002. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -34,7 +34,7 @@ # define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # endif -# if (__SUNPRO_CC <= 0x530) +# if (__SUNPRO_CC <= 0x530) // Requesting debug info (-g) with Boost.Python results // in an internal compiler error for "static const" // initialized in-class. @@ -57,7 +57,7 @@ # define BOOST_NO_INTEGRAL_INT64_T # endif -# if (__SUNPRO_CC < 0x570) +# if (__SUNPRO_CC < 0x570) # define BOOST_NO_TEMPLATE_TEMPLATES // see http://lists.boost.org/MailArchives/boost/msg47184.php // and http://lists.boost.org/MailArchives/boost/msg47220.php @@ -65,7 +65,7 @@ # define BOOST_NO_SFINAE # define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS # endif -# if (__SUNPRO_CC <= 0x580) +# if (__SUNPRO_CC <= 0x580) # define BOOST_NO_IS_ABSTRACT # endif @@ -128,6 +128,9 @@ #define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES // // Version diff --git a/cpp/BoostParts/boost/config/compiler/vacpp.hpp b/cpp/BoostParts/boost/config/compiler/vacpp.hpp index 47b99031..17c02f91 100644 --- a/cpp/BoostParts/boost/config/compiler/vacpp.hpp +++ b/cpp/BoostParts/boost/config/compiler/vacpp.hpp @@ -1,10 +1,10 @@ -// (C) Copyright John Maddock 2001 - 2003. -// (C) Copyright Toon Knapen 2001 - 2003. -// (C) Copyright Lie-Quan Lee 2001. -// (C) Copyright Markus Schoepflin 2002 - 2003. -// (C) Copyright Beman Dawes 2002 - 2003. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schoepflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -16,7 +16,7 @@ # define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS #endif -#if (__IBMCPP__ <= 502) +#if (__IBMCPP__ <= 502) // Actually the compiler supports inclass member initialization but it // requires a definition for the class member and it doesn't recognize // it as an integral constant expression when used as a template argument. @@ -30,9 +30,9 @@ #endif #if (__IBMCPP__ <= 1110) -// XL C++ V11.1 and earlier versions may not always value-initialize -// a temporary object T(), when T is a non-POD aggregate class type. -// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it +// XL C++ V11.1 and earlier versions may not always value-initialize +// a temporary object T(), when T is a non-POD aggregate class type. +// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it // high priority. -- Niels Dekker (LKEB), May 2010. # define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #endif @@ -126,6 +126,6 @@ #if ! __C99_MACRO_WITH_VA_ARGS # define BOOST_NO_CXX11_VARIADIC_MACROS #endif - - - +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES diff --git a/cpp/BoostParts/boost/config/compiler/visualc.hpp b/cpp/BoostParts/boost/config/compiler/visualc.hpp index 83e8e3d7..695fa943 100644 --- a/cpp/BoostParts/boost/config/compiler/visualc.hpp +++ b/cpp/BoostParts/boost/config/compiler/visualc.hpp @@ -1,11 +1,11 @@ -// (C) Copyright John Maddock 2001 - 2003. -// (C) Copyright Darin Adler 2001 - 2002. -// (C) Copyright Peter Dimov 2001. -// (C) Copyright Aleksey Gurtovoy 2002. -// (C) Copyright David Abrahams 2002 - 2003. -// (C) Copyright Beman Dawes 2002 - 2003. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to 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) // See http://www.boost.org for most recent version. @@ -34,67 +34,20 @@ // Attempt to suppress VC6 warnings about the length of decorated names (obsolete): #pragma warning( disable : 4503 ) // warning: decorated name length exceeded +#define BOOST_HAS_PRAGMA_ONCE + // // versions check: -// we don't support Visual C++ prior to version 6: -#if _MSC_VER < 1200 +// we don't support Visual C++ prior to version 7.1: +#if _MSC_VER < 1310 # error "Compiler not supported or configured - please reconfigure" #endif -#if _MSC_VER < 1300 // 1200 == VC++ 6.0, 1200-1202 == eVC++4 -# pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info -# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS -# define BOOST_NO_VOID_RETURNS -# define BOOST_NO_EXCEPTION_STD_NAMESPACE - -# if _MSC_VER == 1202 -# define BOOST_NO_STD_TYPEINFO -# endif - +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_FENV_H #endif -/// Visual Studio has no fenv.h -#define BOOST_NO_FENV_H - -#if (_MSC_VER < 1310) // 130X == VC++ 7.0 - -# if !defined(_MSC_EXTENSIONS) && !defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) // VC7 bug with /Za -# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS -# endif - -# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION -# define BOOST_NO_PRIVATE_IN_AGGREGATE -# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -# define BOOST_NO_INTEGRAL_INT64_T -# define BOOST_NO_DEDUCED_TYPENAME -# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE - -// VC++ 6/7 has member templates but they have numerous problems including -// cases of silent failure, so for safety we define: -# define BOOST_NO_MEMBER_TEMPLATES -// For VC++ experts wishing to attempt workarounds, we define: -# define BOOST_MSVC6_MEMBER_TEMPLATES - -# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS -# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# define BOOST_NO_CV_VOID_SPECIALIZATIONS -# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING -# define BOOST_NO_USING_TEMPLATE -# define BOOST_NO_SWPRINTF -# define BOOST_NO_TEMPLATE_TEMPLATES -# define BOOST_NO_SFINAE -# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS -# define BOOST_NO_IS_ABSTRACT -# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS -// TODO: what version is meant here? Have there really been any fixes in cl 12.01 (as e.g. shipped with eVC4)? -# if (_MSC_VER >= 1300) -# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS -# endif - -#endif - -#if _MSC_VER < 1400 +#if _MSC_VER < 1400 // although a conforming signature for swprint exists in VC7.1 // it appears not to actually work: # define BOOST_NO_SWPRINTF @@ -119,9 +72,9 @@ #endif -// MSVC (including the latest checked version) has not yet completely +// MSVC (including the latest checked version) has not yet completely // implemented value-initialization, as is reported: -// "VC++ does not value-initialize members of derived classes without +// "VC++ does not value-initialize members of derived classes without // user-declared constructor", reported in 2009 by Sylvester Hesp: // https://connect.microsoft.com/VisualStudio/feedback/details/484295 // "Presence of copy constructor breaks member class initialization", @@ -148,19 +101,17 @@ # define BOOST_HAS_GETSYSTEMTIMEASFILETIME #endif -// -// check for exception handling support: +// +// check for exception handling support: #if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) -# define BOOST_NO_EXCEPTIONS -#endif +# define BOOST_NO_EXCEPTIONS +#endif // // __int64 support: // -#if (_MSC_VER >= 1200) -# define BOOST_HAS_MS_INT64 -#endif -#if (_MSC_VER >= 1310) && (defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400)) +#define BOOST_HAS_MS_INT64 +#if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400) # define BOOST_HAS_LONG_LONG #else # define BOOST_NO_LONG_LONG @@ -210,21 +161,23 @@ # define BOOST_HAS_STDINT_H #endif -// C++ features supported by VC++ 11 (aka 2012) +// C++11 features supported by VC++ 11 (aka 2012) // #if _MSC_VER < 1700 # define BOOST_NO_CXX11_RANGE_BASED_FOR # define BOOST_NO_CXX11_SCOPED_ENUMS #endif // _MSC_VER < 1700 -// C++11 features supported by VC++ 11 (aka 2012) November 2012 CTP -// Because the CTP is unsupported, unrelease, and only alpha quality, -// it is only supported if BOOST_MSVC_ENABLE_2012_NOV_CTP is defined. +// C++11 features supported by VC++ 12 (aka 2013). // -#if _MSC_FULL_VER < 170051025 || !defined(BOOST_MSVC_ENABLE_2012_NOV_CTP) +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES # define BOOST_NO_CXX11_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #endif @@ -234,14 +187,13 @@ #define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_DECLTYPE_N3276 -#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS -#define BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_NO_CXX11_NOEXCEPT -#define BOOST_NO_CXX11_TEMPLATE_ALIASES #define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_SFINAE_EXPR #define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_INLINE_NAMESPACES // // prefix and suffix headers: @@ -255,17 +207,13 @@ #ifndef BOOST_COMPILER // TODO: -// these things are mostly bogus. 1200 means version 12.0 of the compiler. The +// these things are mostly bogus. 1200 means version 12.0 of the compiler. The // artificial versions assigned to them only refer to the versions of some IDE // these compilers have been shipped with, and even that is not all of it. Some // were shipped with freely downloadable SDKs, others as crosscompilers in eVC. // IOW, you can't use these 'versions' in any sensible way. Sorry. # if defined(UNDER_CE) -# if _MSC_VER < 1200 - // Note: these are so far off, they are not really supported -# elif _MSC_VER < 1300 // eVC++ 4 comes with 1200-1202 -# define BOOST_COMPILER_VERSION evc4.0 -# elif _MSC_VER < 1400 +# if _MSC_VER < 1400 // Note: I'm not aware of any CE compiler with version 13xx # if defined(BOOST_ASSERT_CONFIG) # error "Unknown EVC++ compiler version - please run the configure tests and report the results" @@ -280,6 +228,8 @@ # define BOOST_COMPILER_VERSION evc10 # elif _MSC_VER < 1800 # define BOOST_COMPILER_VERSION evc11 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION evc12 # else # if defined(BOOST_ASSERT_CONFIG) # error "Unknown EVC++ compiler version - please run the configure tests and report the results" @@ -288,11 +238,11 @@ # endif # endif # else -# if _MSC_VER < 1200 - // Note: these are so far off, they are not really supported +# if _MSC_VER < 1310 + // Note: Versions up to 7.0 aren't supported. # define BOOST_COMPILER_VERSION 5.0 # elif _MSC_VER < 1300 -# define BOOST_COMPILER_VERSION 6.0 +# define BOOST_COMPILER_VERSION 6.0 # elif _MSC_VER < 1310 # define BOOST_COMPILER_VERSION 7.0 # elif _MSC_VER < 1400 @@ -304,7 +254,9 @@ # elif _MSC_VER < 1700 # define BOOST_COMPILER_VERSION 10.0 # elif _MSC_VER < 1800 -# define BOOST_COMPILER_VERSION 11.0 +# define BOOST_COMPILER_VERSION 11.0 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION 12.0 # else # define BOOST_COMPILER_VERSION _MSC_VER # endif @@ -314,8 +266,8 @@ #endif // -// last known and checked version is 1700 (VC11, aka 2011): -#if (_MSC_VER > 1700) +// last known and checked version is 18.00.20827.3 (VC12 RC, aka 2013 RC): +#if (_MSC_VER > 1800 && _MSC_FULL_VER > 180020827) # if defined(BOOST_ASSERT_CONFIG) # error "Unknown compiler version - please run the configure tests and report the results" # else diff --git a/cpp/BoostParts/boost/config/select_compiler_config.hpp b/cpp/BoostParts/boost/config/select_compiler_config.hpp index 8683d658..0eeb7ad3 100644 --- a/cpp/BoostParts/boost/config/select_compiler_config.hpp +++ b/cpp/BoostParts/boost/config/select_compiler_config.hpp @@ -13,6 +13,12 @@ // locate which compiler we are using and define // BOOST_COMPILER_CONFIG as needed: +#if defined __CUDACC__ +// NVIDIA CUDA C++ compiler for GPU +# include "boost/config/compiler/nvcc.hpp" + +#endif + #if defined(__GCCXML__) // GCC-XML emulates other compilers, it has to appear first here! # define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" @@ -21,10 +27,6 @@ // EDG based Cray compiler: # define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" -#elif defined __CUDACC__ -// NVIDIA CUDA C++ compiler for GPU -# define BOOST_COMPILER_CONFIG "boost/config/compiler/nvcc.hpp" - #elif defined __COMO__ // Comeau C++ # define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" diff --git a/cpp/BoostParts/boost/config/stdlib/dinkumware.hpp b/cpp/BoostParts/boost/config/stdlib/dinkumware.hpp index cef6ff24..a8b68be7 100644 --- a/cpp/BoostParts/boost/config/stdlib/dinkumware.hpp +++ b/cpp/BoostParts/boost/config/stdlib/dinkumware.hpp @@ -110,7 +110,8 @@ # define BOOST_NO_CXX11_SMART_PTR #endif -#if (!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE) +#if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610) # define BOOST_NO_CXX11_HDR_TUPLE #endif @@ -128,10 +129,11 @@ # define BOOST_NO_CXX11_ATOMIC_SMART_PTR #endif +// C++0x headers implemented in 610 (as shipped by Microsoft) // -// C++0x headers not yet (fully) implemented: -// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610 # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif #ifdef _CPPLIB_VER # define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER diff --git a/cpp/BoostParts/boost/config/suffix.hpp b/cpp/BoostParts/boost/config/suffix.hpp index 21591c9e..c55579ea 100644 --- a/cpp/BoostParts/boost/config/suffix.hpp +++ b/cpp/BoostParts/boost/config/suffix.hpp @@ -4,7 +4,7 @@ // Copyright (c) 2001-2003 John Maddock // Copyright (c) 2001 Darin Adler // Copyright (c) 2001 Peter Dimov -// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Bill Kempf // Copyright (c) 2002 Jens Maurer // Copyright (c) 2002-2003 David Abrahams // Copyright (c) 2003 Gennaro Prota @@ -146,7 +146,7 @@ # endif // -// Without partial specialization, partial +// Without partial specialization, partial // specialization with default args won't work either: // # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ @@ -503,69 +503,8 @@ namespace boost{ #endif // BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// -// -// Some compilers have problems with function templates whose template -// parameters don't appear in the function parameter list (basically -// they just link one instantiation of the template in the final -// executable). These macros provide a uniform way to cope with the -// problem with no effects on the calling syntax. -// Example: -// -// #include -// #include -// #include -// -// template -// void f() { std::cout << n << ' '; } -// -// template -// void g() { std::cout << typeid(T).name() << ' '; } -// -// int main() { -// f<1>(); -// f<2>(); -// -// g(); -// g(); -// } -// -// With VC++ 6.0 the output is: -// -// 2 2 double double -// -// To fix it, write -// -// template -// void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... } -// -// template -// void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... } -// - - -#if defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) && defined(__cplusplus) - -# include "boost/type.hpp" -# include "boost/non_type.hpp" - -# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) boost::type* = 0 -# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type* -# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type* = 0 -# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type* - -# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ - , BOOST_EXPLICIT_TEMPLATE_TYPE(t) -# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ - , BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) -# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ - , BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) -# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ - , BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) - -#else - -// no workaround needed: expand to nothing +// These macros are obsolete. Port away and remove. # define BOOST_EXPLICIT_TEMPLATE_TYPE(t) # define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) @@ -577,9 +516,6 @@ namespace boost{ # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) - -#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS - // When BOOST_NO_STD_TYPEINFO is defined, we can just import // the global definition into std namespace: #if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) @@ -632,7 +568,7 @@ namespace std{ using ::type_info; } // Set some default values GPU support // # ifndef BOOST_GPU_ENABLED -# define BOOST_GPU_ENABLED +# define BOOST_GPU_ENABLED # endif // BOOST_FORCEINLINE ---------------------------------------------// @@ -648,6 +584,78 @@ namespace std{ using ::type_info; } # endif #endif +// BOOST_NOINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to prevent a function to be inlined +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# else +# define BOOST_NOINLINE +# endif +#endif + +// Branch prediction hints +// These macros are intended to wrap conditional expressions that yield true or false +// +// if (BOOST_LIKELY(var == 10)) +// { +// // the most probable code here +// } +// +#if !defined(BOOST_LIKELY) +# define BOOST_LIKELY(x) x +#endif +#if !defined(BOOST_UNLIKELY) +# define BOOST_UNLIKELY(x) x +#endif + +// Type and data alignment specification +// +#if !defined(BOOST_NO_CXX11_ALIGNAS) +# define BOOST_ALIGNMENT(x) alignas(x) +#elif defined(_MSC_VER) +# define BOOST_ALIGNMENT(x) __declspec(align(x)) +#elif defined(__GNUC__) +# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) +#else +# define BOOST_NO_ALIGNMENT +# define BOOST_ALIGNMENT(x) +#endif + +// Defaulted and deleted function declaration helpers +// These macros are intended to be inside a class definition. +// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its +// body, which will be used if the compiler doesn't support defaulted functions. +// BOOST_DELETED_FUNCTION only accepts the function declaration. It +// will expand to a private function declaration, if the compiler doesn't support +// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION +// in the end of the class definition. +// +// class my_class +// { +// public: +// // Default-constructible +// BOOST_DEFAULTED_FUNCTION(my_class(), {}) +// // Copying prohibited +// BOOST_DELETED_FUNCTION(my_class(my_class const&)) +// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) +// }; +// +#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; +#else +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body +#endif + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_DELETED_FUNCTION(fun) fun = delete; +#else +# define BOOST_DELETED_FUNCTION(fun) private: fun; +#endif + // // Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined // @@ -696,7 +704,7 @@ namespace std{ using ::type_info; } # define BOOST_NO_0X_HDR_FUTURE #endif -// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST // instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS #ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST # ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST @@ -885,19 +893,19 @@ namespace std{ using ::type_info; } # define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) #endif // -// Helper macro BOOST_FALLTHROUGH -// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended -// fall-through between case labels in a switch statement. We use a definition -// that requires a semicolon after it to avoid at least one type of misuse even -// on unsupported compilers. -// -#ifndef BOOST_FALLTHROUGH -# define BOOST_FALLTHROUGH ((void)0) -#endif +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif // // constexpr workarounds -// +// #if defined(BOOST_NO_CXX11_CONSTEXPR) #define BOOST_CONSTEXPR #define BOOST_CONSTEXPR_OR_CONST const diff --git a/cpp/BoostParts/boost/container/allocator_traits.hpp b/cpp/BoostParts/boost/container/allocator_traits.hpp index 64e4352d..aa8194a4 100644 --- a/cpp/BoostParts/boost/container/allocator_traits.hpp +++ b/cpp/BoostParts/boost/container/allocator_traits.hpp @@ -17,12 +17,13 @@ #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif #include #include +#include #include #include #include @@ -387,6 +388,10 @@ struct allocator_traits #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, ::boost::container::default_init_t) + { ::new((void*)p) T; } #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) ///@endcond diff --git a/cpp/BoostParts/boost/container/container_fwd.hpp b/cpp/BoostParts/boost/container/container_fwd.hpp index bdefd81e..271cc8b1 100644 --- a/cpp/BoostParts/boost/container/container_fwd.hpp +++ b/cpp/BoostParts/boost/container/container_fwd.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP #define BOOST_CONTAINER_CONTAINER_FWD_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -135,20 +135,28 @@ class basic_string; struct ordered_range_t {}; +//! Value used to tag that the input range is +//! guaranteed to be ordered +static const ordered_range_t ordered_range = ordered_range_t(); + //! Type used to tag that the input range is //! guaranteed to be ordered and unique struct ordered_unique_range_t : public ordered_range_t {}; -//! Value used to tag that the input range is -//! guaranteed to be ordered -static const ordered_range_t ordered_range = ordered_range_t(); - //! Value used to tag that the input range is //! guaranteed to be ordered and unique static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); +//! Type used to tag that the input range is +//! guaranteed to be ordered and unique +struct default_init_t +{}; + +//! Value used to tag that the input range is +//! guaranteed to be ordered and unique +static const default_init_t default_init = default_init_t(); /// @cond namespace detail_really_deep_namespace { @@ -161,6 +169,7 @@ struct dummy { (void)ordered_range; (void)ordered_unique_range; + (void)default_init; } }; diff --git a/cpp/BoostParts/boost/container/detail/algorithms.hpp b/cpp/BoostParts/boost/container/detail/algorithms.hpp index 824e44b9..7a4a8684 100644 --- a/cpp/BoostParts/boost/container/detail/algorithms.hpp +++ b/cpp/BoostParts/boost/container/detail/algorithms.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP #define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -35,13 +35,13 @@ namespace boost { namespace container { template -struct is_default_construct_iterator +struct is_value_init_construct_iterator { static const bool value = false; }; template -struct is_default_construct_iterator > +struct is_value_init_construct_iterator > { static const bool value = true; }; @@ -64,11 +64,17 @@ inline void construct_in_place(A &a, T* dest, InpIt source) //#endif template -inline void construct_in_place(A &a, T *dest, default_construct_iterator) +inline void construct_in_place(A &a, T *dest, value_init_construct_iterator) { boost::container::allocator_traits::construct(a, dest); } +template +inline void construct_in_place(A &a, T *dest, default_init_construct_iterator) +{ + boost::container::allocator_traits::construct(a, dest, default_init); +} + template inline void construct_in_place(A &a, T *dest, emplace_iterator ei) { diff --git a/cpp/BoostParts/boost/container/detail/allocation_type.hpp b/cpp/BoostParts/boost/container/detail/allocation_type.hpp index 1ebf20ed..59ae9226 100644 --- a/cpp/BoostParts/boost/container/detail/allocation_type.hpp +++ b/cpp/BoostParts/boost/container/detail/allocation_type.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP #define BOOST_CONTAINER_ALLOCATION_TYPE_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/allocator_version_traits.hpp b/cpp/BoostParts/boost/container/detail/allocator_version_traits.hpp index 4cef676a..6df79da8 100644 --- a/cpp/BoostParts/boost/container/detail/allocator_version_traits.hpp +++ b/cpp/BoostParts/boost/container/detail/allocator_version_traits.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP #define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -92,8 +92,12 @@ struct allocator_version_traits static void deallocate_individual(Allocator &a, multiallocation_chain &holder) { - while(!holder.empty()){ - a.deallocate(holder.pop_front(), 1); + size_type n = holder.size(); + typename multiallocation_chain::iterator it = holder.begin(); + while(n--){ + pointer p = boost::intrusive::pointer_traits::pointer_to(*it); + ++it; + a.deallocate(p, 1); } } diff --git a/cpp/BoostParts/boost/container/detail/config_begin.hpp b/cpp/BoostParts/boost/container/detail/config_begin.hpp index 83c2cfe4..664f0927 100644 --- a/cpp/BoostParts/boost/container/detail/config_begin.hpp +++ b/cpp/BoostParts/boost/container/detail/config_begin.hpp @@ -46,4 +46,5 @@ #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site #pragma warning (disable : 4671) // the copy constructor is inaccessible #pragma warning (disable : 4584) // X is already a base-class of Y + #pragma warning (disable : 4510) // default constructor could not be generated #endif //BOOST_MSVC diff --git a/cpp/BoostParts/boost/container/detail/destroyers.hpp b/cpp/BoostParts/boost/container/detail/destroyers.hpp index f9bfd867..fef8aa04 100644 --- a/cpp/BoostParts/boost/container/detail/destroyers.hpp +++ b/cpp/BoostParts/boost/container/detail/destroyers.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_CONTAINER_DESTROYERS_HPP #define BOOST_CONTAINER_DESTROYERS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -68,6 +68,9 @@ struct scoped_deallocator pointer get() const { return m_ptr; } + void set(const pointer &p) + { m_ptr = p; } + void release() { m_ptr = 0; } }; @@ -87,6 +90,9 @@ struct null_scoped_deallocator pointer get() const { return pointer(); } + + void set(const pointer &) + {} }; //!A deleter for scoped_ptr that deallocates the memory @@ -249,6 +255,11 @@ class scoped_destructor void release() { pv_ = 0; } + + void set(value_type *ptr) { pv_ = ptr; } + + value_type *get() const { return pv_; } + private: value_type *pv_; A &a_; diff --git a/cpp/BoostParts/boost/container/detail/iterators.hpp b/cpp/BoostParts/boost/container/detail/iterators.hpp index bba72058..5766a7c2 100644 --- a/cpp/BoostParts/boost/container/detail/iterators.hpp +++ b/cpp/BoostParts/boost/container/detail/iterators.hpp @@ -14,7 +14,7 @@ #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef BOOST_CONTAINER_PERFECT_FORWARDING #include @@ -147,79 +148,79 @@ class constant_iterator }; template -class default_construct_iterator +class value_init_construct_iterator : public std::iterator { - typedef default_construct_iterator this_type; + typedef value_init_construct_iterator this_type; public: - explicit default_construct_iterator(Difference range_size) + explicit value_init_construct_iterator(Difference range_size) : m_num(range_size){} //Constructors - default_construct_iterator() + value_init_construct_iterator() : m_num(0){} - default_construct_iterator& operator++() + value_init_construct_iterator& operator++() { increment(); return *this; } - default_construct_iterator operator++(int) + value_init_construct_iterator operator++(int) { - default_construct_iterator result (*this); + value_init_construct_iterator result (*this); increment(); return result; } - default_construct_iterator& operator--() + value_init_construct_iterator& operator--() { decrement(); return *this; } - default_construct_iterator operator--(int) + value_init_construct_iterator operator--(int) { - default_construct_iterator result (*this); + value_init_construct_iterator result (*this); decrement(); return result; } - friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i.equal(i2); } - friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i == i2); } - friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i.less(i2); } - friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i2 < i; } - friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i > i2); } - friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) + friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return !(i < i2); } - friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) + friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) { return i2.distance_to(i); } //Arithmetic - default_construct_iterator& operator+=(Difference off) + value_init_construct_iterator& operator+=(Difference off) { this->advance(off); return *this; } - default_construct_iterator operator+(Difference off) const + value_init_construct_iterator operator+(Difference off) const { - default_construct_iterator other(*this); + value_init_construct_iterator other(*this); other.advance(off); return other; } - friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) + friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) { return right + off; } - default_construct_iterator& operator-=(Difference off) + value_init_construct_iterator& operator-=(Difference off) { this->advance(-off); return *this; } - default_construct_iterator operator-(Difference off) const + value_init_construct_iterator operator-(Difference off) const { return *this + (-off); } //This pseudo-iterator's dereference operations have no sense since value is not @@ -257,6 +258,118 @@ class default_construct_iterator { return m_num - other.m_num; } }; +template +class default_init_construct_iterator + : public std::iterator + +{ + typedef default_init_construct_iterator this_type; + + public: + explicit default_init_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + default_init_construct_iterator() + : m_num(0){} + + default_init_construct_iterator& operator++() + { increment(); return *this; } + + default_init_construct_iterator operator++(int) + { + default_init_construct_iterator result (*this); + increment(); + return result; + } + + default_init_construct_iterator& operator--() + { decrement(); return *this; } + + default_init_construct_iterator operator--(int) + { + default_init_construct_iterator result (*this); + decrement(); + return result; + } + + friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + default_init_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + default_init_construct_iterator operator+(Difference off) const + { + default_init_construct_iterator other(*this); + other.advance(off); + return other; + } + + friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) + { return right + off; } + + default_init_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + default_init_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + //const T& operator*() const; + //const T& operator[](difference_type) const; + //const T* operator->() const; + + private: + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { + static T dummy; + return dummy; + } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + + template class repeat_iterator : public std::iterator @@ -585,24 +698,112 @@ struct is_bidirectional_iterator static const bool value = false; }; -template +template struct iiterator_types { + typedef typename IIterator::value_type it_value_type; + typedef typename it_value_type::value_type value_type; typedef typename std::iterator_traits::pointer it_pointer; typedef typename std::iterator_traits::difference_type difference_type; typedef typename ::boost::intrusive::pointer_traits:: - template rebind_pointer::type pointer; + template rebind_pointer::type pointer; typedef typename ::boost::intrusive::pointer_traits:: - template rebind_pointer::type const_pointer; + template rebind_pointer::type const_pointer; typedef typename ::boost::intrusive:: pointer_traits::reference reference; typedef typename ::boost::intrusive:: pointer_traits::reference const_reference; + typedef typename IIterator::iterator_category iterator_category; }; +template +struct std_iterator +{ + typedef typename std::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::const_pointer + , typename iiterator_types::const_reference> type; +}; + +template +struct std_iterator +{ + typedef typename std::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::pointer + , typename iiterator_types::reference> type; +}; + +template +class iterator + : public std_iterator::type +{ + typedef typename std_iterator::type types_t; + + public: + typedef typename types_t::value_type value_type; + typedef typename types_t::pointer pointer; + typedef typename types_t::reference reference; + + iterator() + {} + + explicit iterator(IIterator iit) BOOST_CONTAINER_NOEXCEPT + : m_iit(iit) + {} + + iterator(iterator const& other) BOOST_CONTAINER_NOEXCEPT + : m_iit(other.get()) + {} + + iterator& operator++() BOOST_CONTAINER_NOEXCEPT + { ++this->m_iit; return *this; } + + iterator operator++(int) BOOST_CONTAINER_NOEXCEPT + { + iterator result (*this); + ++this->m_iit; + return result; + } + + iterator& operator--() BOOST_CONTAINER_NOEXCEPT + { + //If the iterator is not a bidirectional iterator, operator-- should not exist + BOOST_STATIC_ASSERT((is_bidirectional_iterator::value)); + --this->m_iit; return *this; + } + + iterator operator--(int) BOOST_CONTAINER_NOEXCEPT + { + iterator result (*this); + --this->m_iit; + return result; + } + + friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT + { return l.m_iit == r.m_iit; } + + friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT + { return !(l == r); } + + reference operator*() const BOOST_CONTAINER_NOEXCEPT + { return (*this->m_iit).get_data(); } + + pointer operator->() const BOOST_CONTAINER_NOEXCEPT + { return ::boost::intrusive::pointer_traits::pointer_to(this->operator*()); } + + const IIterator &get() const BOOST_CONTAINER_NOEXCEPT + { return this->m_iit; } + + private: + IIterator m_iit; +}; } //namespace container_detail { - } //namespace container { } //namespace boost { diff --git a/cpp/BoostParts/boost/container/detail/memory_util.hpp b/cpp/BoostParts/boost/container/detail/memory_util.hpp index ac9a8998..ed899548 100644 --- a/cpp/BoostParts/boost/container/detail/memory_util.hpp +++ b/cpp/BoostParts/boost/container/detail/memory_util.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP #define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/mpl.hpp b/cpp/BoostParts/boost/container/detail/mpl.hpp index 74a1ce0e..08f3eae5 100644 --- a/cpp/BoostParts/boost/container/detail/mpl.hpp +++ b/cpp/BoostParts/boost/container/detail/mpl.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/multiallocation_chain.hpp b/cpp/BoostParts/boost/container/detail/multiallocation_chain.hpp index 2e29f9c1..bc9945ac 100644 --- a/cpp/BoostParts/boost/container/detail/multiallocation_chain.hpp +++ b/cpp/BoostParts/boost/container/detail/multiallocation_chain.hpp @@ -243,10 +243,10 @@ class transform_multiallocation_chain iterator before_begin() { return iterator(holder_.before_begin()); } - +*/ iterator begin() - { return iterator(holder_.begin()); } - + { return iterator(this->MultiallocationChain::begin()); } +/* iterator end() { return iterator(holder_.end()); } diff --git a/cpp/BoostParts/boost/container/detail/node_alloc_holder.hpp b/cpp/BoostParts/boost/container/detail/node_alloc_holder.hpp index 5a94a68d..d94c2e9f 100644 --- a/cpp/BoostParts/boost/container/detail/node_alloc_holder.hpp +++ b/cpp/BoostParts/boost/container/detail/node_alloc_holder.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_ #define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_ -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -53,10 +54,14 @@ struct node_compare typedef typename ValueCompare::value_type value_type; typedef typename ValueCompare::key_of_value key_of_value; - node_compare(const ValueCompare &pred) + explicit node_compare(const ValueCompare &pred) : ValueCompare(pred) {} + node_compare() + : ValueCompare() + {} + ValueCompare &value_comp() { return static_cast(*this); } @@ -67,16 +72,16 @@ struct node_compare { return ValueCompare::operator()(a.get_data(), b.get_data()); } }; -template +template struct node_alloc_holder { typedef allocator_traits allocator_traits_type; - typedef node_alloc_holder self_t; typedef typename allocator_traits_type::value_type value_type; typedef typename ICont::value_type Node; typedef typename allocator_traits_type::template portable_rebind_alloc::type NodeAlloc; typedef allocator_traits node_allocator_traits_type; + typedef container_detail::allocator_version_traits node_allocator_version_traits_type; typedef A ValAlloc; typedef typename node_allocator_traits_type::pointer NodePtr; typedef container_detail::scoped_deallocator Deallocator; @@ -116,20 +121,20 @@ struct node_alloc_holder { this->icont().swap(x.icont()); } //Constructors for associative containers - explicit node_alloc_holder(const ValAlloc &a, const Pred &c) + explicit node_alloc_holder(const ValAlloc &a, const ValPred &c) : members_(a, c) {} - explicit node_alloc_holder(const node_alloc_holder &x, const Pred &c) + explicit node_alloc_holder(const node_alloc_holder &x, const ValPred &c) : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c) {} - explicit node_alloc_holder(const Pred &c) + explicit node_alloc_holder(const ValPred &c) : members_(c) {} //helpers for move assignments - explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const Pred &c) + explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const ValPred &c) : members_(boost::move(x.node_alloc()), c) { this->icont().swap(x.icont()); } @@ -230,45 +235,41 @@ struct node_alloc_holder (FwdIterator beg, difference_type n, Inserter inserter) { if(n){ - /* - NodePtr p = this->allocate_one(); - Deallocator node_deallocator(p, this->node_alloc()); - ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it); - node_deallocator.release(); - //This does not throw - typedef typename Node::hook_type hook_type; - ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type; - return (p); - */ - typedef typename NodeAlloc::multiallocation_chain multiallocation_chain; + typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain; //Try to allocate memory in a single block typedef typename multiallocation_chain::iterator multialloc_iterator; multiallocation_chain mem; - this->node_alloc().allocate_individual(n, mem); + NodeAlloc &nalloc = this->node_alloc(); + node_allocator_version_traits_type::allocate_individual(nalloc, n, mem); multialloc_iterator itbeg(mem.begin()), itlast(mem.last()); mem.clear(); Node *p = 0; - NodeAlloc &nalloc = this->node_alloc(); BOOST_TRY{ + Deallocator node_deallocator(NodePtr(), nalloc); + container_detail::scoped_destructor sdestructor(nalloc, 0); while(n--){ p = container_detail::to_raw_pointer(&*itbeg); + node_deallocator.set(p); ++itbeg; //This can throw - Deallocator node_deallocator(p, nalloc); boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg); + sdestructor.set(p); ++beg; - node_deallocator.release(); //This does not throw typedef typename Node::hook_type hook_type; ::new(static_cast(p)) hook_type; - //This can throw in some containers (predicate might throw) + //This can throw in some containers (predicate might throw). + //(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception) inserter(*p); + sdestructor.set(0); } + sdestructor.release(); + node_deallocator.release(); } BOOST_CATCH(...){ mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n); - this->node_alloc().deallocate_individual(mem); + node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem); BOOST_RETHROW } BOOST_CATCH_END @@ -345,12 +346,12 @@ struct node_alloc_holder {} template - members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const Pred &c) + members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const ValPred &c) : NodeAlloc(boost::forward(c2alloc)) , m_icont(typename ICont::value_compare(c)) {} - explicit members_holder(const Pred &c) + explicit members_holder(const ValPred &c) : NodeAlloc() , m_icont(typename ICont::value_compare(c)) {} diff --git a/cpp/BoostParts/boost/container/detail/pair.hpp b/cpp/BoostParts/boost/container/detail/pair.hpp index 79753a86..bfe7978c 100644 --- a/cpp/BoostParts/boost/container/detail/pair.hpp +++ b/cpp/BoostParts/boost/container/detail/pair.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/preprocessor.hpp b/cpp/BoostParts/boost/container/detail/preprocessor.hpp index 4e175a82..41d1f553 100644 --- a/cpp/BoostParts/boost/container/detail/preprocessor.hpp +++ b/cpp/BoostParts/boost/container/detail/preprocessor.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP #define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/transform_iterator.hpp b/cpp/BoostParts/boost/container/detail/transform_iterator.hpp index 98f5c04d..c40ecc6b 100644 --- a/cpp/BoostParts/boost/container/detail/transform_iterator.hpp +++ b/cpp/BoostParts/boost/container/detail/transform_iterator.hpp @@ -14,7 +14,7 @@ #ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP #define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/tree.hpp b/cpp/BoostParts/boost/container/detail/tree.hpp index 9cb3c9f8..7400a1a8 100644 --- a/cpp/BoostParts/boost/container/detail/tree.hpp +++ b/cpp/BoostParts/boost/container/detail/tree.hpp @@ -20,8 +20,8 @@ #include #include #include - #include +#include #include #include #include @@ -50,8 +50,12 @@ struct tree_value_compare typedef KeyOfValue key_of_value; typedef Key key_type; - tree_value_compare(const key_compare &kcomp) - : key_compare(kcomp) + explicit tree_value_compare(const key_compare &kcomp) + : KeyCompare(kcomp) + {} + + tree_value_compare() + : KeyCompare() {} const key_compare &key_comp() const @@ -174,6 +178,34 @@ struct rbtree_node { m_data = ::boost::move(v); } }; +template +class insert_equal_end_hint_functor +{ + Icont &icont_; + + public: + insert_equal_end_hint_functor(Icont &icont) + : icont_(icont) + {} + + void operator()(Node &n) + { this->icont_.insert_equal(this->icont_.cend(), n); } +}; + +template +class push_back_functor +{ + Icont &icont_; + + public: + push_back_functor(Icont &icont) + : icont_(icont) + {} + + void operator()(Node &n) + { this->icont_.push_back(n); } +}; + }//namespace container_detail { namespace container_detail { @@ -212,15 +244,15 @@ class rbtree , typename container_detail::intrusive_rbtree_type >::type - , KeyCompare + , tree_value_compare > { + typedef tree_value_compare + ValComp; typedef typename container_detail::intrusive_rbtree_type - < A, tree_value_compare - - >::type Icont; + < A, ValComp>::type Icont; typedef container_detail::node_alloc_holder - AllocHolder; + AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; typedef rbtree < Key, Value, KeyOfValue , KeyCompare, A> ThisType; @@ -318,8 +350,7 @@ class rbtree typedef Value value_type; typedef A allocator_type; typedef KeyCompare key_compare; - typedef tree_value_compare< Key, Value - , KeyCompare, KeyOfValue> value_compare; + typedef ValComp value_compare; typedef typename boost::container:: allocator_traits::pointer pointer; typedef typename boost::container:: @@ -373,109 +404,21 @@ class rbtree typedef key_node_compare KeyNodeCompare; public: - //rbtree const_iterator - class const_iterator - : public std::iterator - < std::bidirectional_iterator_tag - , value_type , rbtree_difference_type - , rbtree_const_pointer , rbtree_const_reference> - { - protected: - typedef typename Icont::iterator iiterator; - iiterator m_it; - explicit const_iterator(iiterator it) : m_it(it){} - void prot_incr() { ++m_it; } - void prot_decr() { --m_it; } - - private: - iiterator get() - { return this->m_it; } - - public: - friend class rbtree ; - typedef rbtree_difference_type difference_type; - - //Constructors - const_iterator() - : m_it() - {} - - //Pointer like operators - const_reference operator*() const - { return m_it->get_data(); } - - const_pointer operator->() const - { return const_pointer(&m_it->get_data()); } - - //Increment / Decrement - const_iterator& operator++() - { prot_incr(); return *this; } - - const_iterator operator++(int) - { iiterator tmp = m_it; ++*this; return const_iterator(tmp); } - - const_iterator& operator--() - { prot_decr(); return *this; } - - const_iterator operator--(int) - { iiterator tmp = m_it; --*this; return const_iterator(tmp); } - - //Comparison operators - bool operator== (const const_iterator& r) const - { return m_it == r.m_it; } - - bool operator!= (const const_iterator& r) const - { return m_it != r.m_it; } - }; - - //rbtree iterator - class iterator : public const_iterator - { - private: - explicit iterator(iiterator it) - : const_iterator(it) - {} - - iiterator get() - { return this->m_it; } - - public: - friend class rbtree ; - typedef rbtree_pointer pointer; - typedef rbtree_reference reference; - - //Constructors - iterator(){} - - //Pointer like operators - reference operator*() const - { return this->m_it->get_data(); } - pointer operator->() const - { return boost::intrusive::pointer_traits::pointer_to(this->m_it->get_data()); } - - //Increment / Decrement - iterator& operator++() - { this->prot_incr(); return *this; } - - iterator operator++(int) - { iiterator tmp = this->m_it; ++*this; return iterator(tmp); } - - iterator& operator--() - { this->prot_decr(); return *this; } - - iterator operator--(int) - { iterator tmp = *this; --*this; return tmp; } - }; - + typedef container_detail::iterator iterator; + typedef container_detail::iterator const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; rbtree() - : AllocHolder(key_compare()) + : AllocHolder(ValComp(key_compare())) {} - rbtree(const key_compare& comp, const allocator_type& a = allocator_type()) - : AllocHolder(a, comp) + explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type()) + : AllocHolder(a, ValComp(comp)) + {} + + explicit rbtree(const allocator_type& a) + : AllocHolder(a) {} template @@ -488,13 +431,21 @@ class rbtree >::type * = 0 #endif ) - : AllocHolder(a, comp) + : AllocHolder(a, value_compare(comp)) { + //Use cend() as hint to achieve linear time for + //ordered ranges as required by the standard + //for the constructor + const const_iterator end_it(this->cend()); if(unique_insertion){ - this->insert_unique(first, last); + for ( ; first != last; ++first){ + this->insert_unique(end_it, *first); + } } else{ - this->insert_equal(first, last); + for ( ; first != last; ++first){ + this->insert_equal(end_it, *first); + } } } @@ -508,15 +459,22 @@ class rbtree >::type * = 0 #endif ) - : AllocHolder(a, comp) + : AllocHolder(a, value_compare(comp)) { if(unique_insertion){ - this->insert_unique(first, last); + //Use cend() as hint to achieve linear time for + //ordered ranges as required by the standard + //for the constructor + const const_iterator end_it(this->cend()); + for ( ; first != last; ++first){ + this->insert_unique(end_it, *first); + } } else{ //Optimized allocation and construction this->allocate_many_and_construct - (first, std::distance(first, last), insert_equal_end_hint_functor(this->icont())); + ( first, std::distance(first, last) + , insert_equal_end_hint_functor(this->icont())); } } @@ -530,9 +488,11 @@ class rbtree >::type * = 0 #endif ) - : AllocHolder(a, comp) + : AllocHolder(a, value_compare(comp)) { - this->insert_equal(first, last); + for ( ; first != last; ++first){ + this->push_back_impl(*first); + } } template @@ -545,33 +505,34 @@ class rbtree >::type * = 0 #endif ) - : AllocHolder(a, comp) + : AllocHolder(a, value_compare(comp)) { //Optimized allocation and construction this->allocate_many_and_construct - (first, std::distance(first, last), push_back_functor(this->icont())); + ( first, std::distance(first, last) + , container_detail::push_back_functor(this->icont())); } rbtree(const rbtree& x) - : AllocHolder(x, x.key_comp()) + : AllocHolder(x, x.value_comp()) { this->icont().clone_from (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); } rbtree(BOOST_RV_REF(rbtree) x) - : AllocHolder(::boost::move(static_cast(x)), x.key_comp()) + : AllocHolder(::boost::move(static_cast(x)), x.value_comp()) {} rbtree(const rbtree& x, const allocator_type &a) - : AllocHolder(a, x.key_comp()) + : AllocHolder(a, x.value_comp()) { this->icont().clone_from (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); } rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a) - : AllocHolder(a, x.key_comp()) + : AllocHolder(a, x.value_comp()) { if(this->node_alloc() == x.node_alloc()){ this->icont().swap(x.icont()); @@ -619,8 +580,8 @@ class rbtree rbtree& operator=(BOOST_RV_REF(rbtree) x) { if (&x != this){ - NodeAlloc &this_alloc = this->node_alloc(); - NodeAlloc &x_alloc = x.node_alloc(); + NodeAlloc &this_alloc = this->get_stored_allocator(); + const NodeAlloc &x_alloc = x.get_stored_allocator(); //If allocators are equal we can just swap pointers if(this_alloc == x_alloc){ //Destroy and swap pointers @@ -763,8 +724,10 @@ class rbtree iterator insert_unique_commit(const value_type& v, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(v); - iiterator it(this->icont().insert_unique_commit(*tmp, data)); - return iterator(it); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_unique_commit(*tmp, data)); + destroy_deallocator.release(); + return ret; } template @@ -772,8 +735,10 @@ class rbtree (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data) { NodePtr tmp = AllocHolder::create_node(boost::forward(mv)); - iiterator it(this->icont().insert_unique_commit(*tmp, data)); - return iterator(it); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_unique_commit(*tmp, data)); + destroy_deallocator.release(); + return ret; } std::pair insert_unique(const value_type& v) @@ -781,10 +746,10 @@ class rbtree insert_commit_data data; std::pair ret = this->insert_unique_check(KeyOfValue()(v), data); - if(!ret.second) - return ret; - return std::pair - (this->insert_unique_commit(v, data), true); + if(ret.second){ + ret.first = this->insert_unique_commit(v, data); + } + return ret; } template @@ -793,13 +758,22 @@ class rbtree insert_commit_data data; std::pair ret = this->insert_unique_check(KeyOfValue()(mv), data); - if(!ret.second) - return ret; - return std::pair - (this->insert_unique_commit(boost::forward(mv), data), true); + if(ret.second){ + ret.first = this->insert_unique_commit(boost::forward(mv), data); + } + return ret; } private: + + template + void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv) + { + NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + //push_back has no-throw guarantee so avoid any deallocator/destroyer + this->icont().push_back(*tmp); + } + std::pair emplace_unique_impl(NodePtr p) { value_type &v = p->get_data(); @@ -845,15 +819,21 @@ class rbtree template iterator emplace_equal(Args&&... args) { - NodePtr p(AllocHolder::create_node(boost::forward(args)...)); - return iterator(this->icont().insert_equal(this->icont().end(), *p)); + NodePtr tmp(AllocHolder::create_node(boost::forward(args)...)); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); + destroy_deallocator.release(); + return ret; } template iterator emplace_hint_equal(const_iterator hint, Args&&... args) { - NodePtr p(AllocHolder::create_node(boost::forward(args)...)); - return iterator(this->icont().insert_equal(hint.get(), *p)); + NodePtr tmp(AllocHolder::create_node(boost::forward(args)...)); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(hint.get(), *tmp)); + destroy_deallocator.release(); + return ret; } #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING @@ -877,16 +857,22 @@ class rbtree BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { \ - NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - return iterator(this->icont().insert_equal(this->icont().end(), *p)); \ + NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); \ + iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \ + destroy_deallocator.release(); \ + return ret; \ } \ \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ iterator emplace_hint_equal(const_iterator hint \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { \ - NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ - return iterator(this->icont().insert_equal(hint.get(), *p)); \ + NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); \ + iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \ + destroy_deallocator.release(); \ + return ret; \ } \ //! #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) @@ -918,53 +904,53 @@ class rbtree template void insert_unique(InputIterator first, InputIterator last) { - if(this->empty()){ - //Insert with end hint, to achieve linear - //complexity if [first, last) is ordered - const_iterator hint(this->cend()); - for( ; first != last; ++first) - hint = this->insert_unique(hint, *first); - } - else{ - for( ; first != last; ++first) - this->insert_unique(*first); - } + for( ; first != last; ++first) + this->insert_unique(*first); } iterator insert_equal(const value_type& v) { - NodePtr p(AllocHolder::create_node(v)); - return iterator(this->icont().insert_equal(this->icont().end(), *p)); + NodePtr tmp(AllocHolder::create_node(v)); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); + destroy_deallocator.release(); + return ret; } template iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv) { - NodePtr p(AllocHolder::create_node(boost::forward(mv))); - return iterator(this->icont().insert_equal(this->icont().end(), *p)); + NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); + destroy_deallocator.release(); + return ret; } iterator insert_equal(const_iterator hint, const value_type& v) { - NodePtr p(AllocHolder::create_node(v)); - return iterator(this->icont().insert_equal(hint.get(), *p)); + NodePtr tmp(AllocHolder::create_node(v)); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(hint.get(), *tmp)); + destroy_deallocator.release(); + return ret; } template iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv) { - NodePtr p(AllocHolder::create_node(boost::forward(mv))); - return iterator(this->icont().insert_equal(hint.get(), *p)); + NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); + iterator ret(this->icont().insert_equal(hint.get(), *tmp)); + destroy_deallocator.release(); + return ret; } template void insert_equal(InputIterator first, InputIterator last) { - //Insert with end hint, to achieve linear - //complexity if [first, last) is ordered - const_iterator hint(this->cend()); for( ; first != last; ++first) - hint = this->insert_equal(hint, *first); + this->insert_equal(*first); } iterator erase(const_iterator position) @@ -1015,41 +1001,6 @@ class rbtree return std::pair (const_iterator(ret.first), const_iterator(ret.second)); } - - private: - - class insert_equal_end_hint_functor; - friend class insert_equal_end_hint_functor; - - class insert_equal_end_hint_functor - { - Icont &icont_; - const iconst_iterator cend_; - - public: - insert_equal_end_hint_functor(Icont &icont) - : icont_(icont), cend_(this->icont_.cend()) - {} - - void operator()(Node &n) - { this->icont_.insert_equal(cend_, n); } - }; - - class push_back_functor; - friend class push_back_functor; - - class push_back_functor - { - Icont &icont_; - - public: - push_back_functor(Icont &icont) - : icont_(icont) - {} - - void operator()(Node &n) - { this->icont_.push_back(n); } - }; }; template = 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/utilities.hpp b/cpp/BoostParts/boost/container/detail/utilities.hpp index 81e0ed8f..c42087c2 100644 --- a/cpp/BoostParts/boost/container/detail/utilities.hpp +++ b/cpp/BoostParts/boost/container/detail/utilities.hpp @@ -12,6 +12,7 @@ #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP #include "config_begin.hpp" +#include "workaround.hpp" #include #include //for ::memcpy #include @@ -621,7 +622,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible:: ////////////////////////////////////////////////////////////////////////////// // -// uninitialized_default_alloc_n +// uninitialized_value_init_alloc_n // ////////////////////////////////////////////////////////////////////////////// @@ -635,7 +636,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible:: template // F models ForwardIterator -inline F uninitialized_default_alloc_n(A &a, typename allocator_traits::difference_type n, F r) +inline F uninitialized_value_init_alloc_n(A &a, typename allocator_traits::difference_type n, F r) { F back = r; BOOST_TRY{ @@ -654,6 +655,41 @@ inline F uninitialized_default_alloc_n(A &a, typename allocator_traits::diffe return r; } +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_default_init_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits::difference_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, container_detail::to_raw_pointer(&*r), default_init); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, container_detail::to_raw_pointer(&*back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + ////////////////////////////////////////////////////////////////////////////// // // uninitialized_fill_alloc @@ -1055,18 +1091,21 @@ inline typename container_detail::enable_if_c ::memcpy(short_ptr, stora_ptr, sizeof_storage); large_ptr += sizeof_storage; short_ptr += sizeof_storage; + BOOST_CONTAINER_FALLTHOUGH case 3: ::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage); ::memcpy(short_ptr, stora_ptr, sizeof_storage); large_ptr += sizeof_storage; short_ptr += sizeof_storage; + BOOST_CONTAINER_FALLTHOUGH case 2: ::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage); ::memcpy(short_ptr, stora_ptr, sizeof_storage); large_ptr += sizeof_storage; short_ptr += sizeof_storage; + BOOST_CONTAINER_FALLTHOUGH case 1: ::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage); diff --git a/cpp/BoostParts/boost/container/detail/value_init.hpp b/cpp/BoostParts/boost/container/detail/value_init.hpp index ec1a99c5..afe5b15a 100644 --- a/cpp/BoostParts/boost/container/detail/value_init.hpp +++ b/cpp/BoostParts/boost/container/detail/value_init.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP #define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/variadic_templates_tools.hpp b/cpp/BoostParts/boost/container/detail/variadic_templates_tools.hpp index d903dfa0..cce7fede 100644 --- a/cpp/BoostParts/boost/container/detail/variadic_templates_tools.hpp +++ b/cpp/BoostParts/boost/container/detail/variadic_templates_tools.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP #define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/detail/workaround.hpp b/cpp/BoostParts/boost/container/detail/workaround.hpp index 06cb7337..49fe284b 100644 --- a/cpp/BoostParts/boost/container/detail/workaround.hpp +++ b/cpp/BoostParts/boost/container/detail/workaround.hpp @@ -35,6 +35,12 @@ #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST #endif +#if !defined(BOOST_FALLTHOUGH) + #define BOOST_CONTAINER_FALLTHOUGH +#else + #define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH; +#endif + //Macros for documentation purposes. For code, expands to the argument #define BOOST_CONTAINER_IMPDEF(TYPE) TYPE #define BOOST_CONTAINER_SEEDOC(TYPE) TYPE diff --git a/cpp/BoostParts/boost/container/map.hpp b/cpp/BoostParts/boost/container/map.hpp index b1faf495..f4776e88 100644 --- a/cpp/BoostParts/boost/container/map.hpp +++ b/cpp/BoostParts/boost/container/map.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_MAP_HPP #define BOOST_CONTAINER_MAP_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -138,6 +138,16 @@ class map BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } + //! Effects: Constructs an empty map using the specified allocator. + //! + //! Complexity: Constant. + explicit map(const allocator_type& a) + : m_tree(a) + { + //Allocator type must be std::pair + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); + } + //! Effects: Constructs an empty map using the specified comparison object and //! allocator, and inserts elements from the range [first ,last ). //! @@ -160,6 +170,8 @@ class map //! unique values. //! //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. template map( ordered_unique_range_t, InputIterator first, InputIterator last , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) @@ -701,7 +713,7 @@ class map //! //! Complexity: log(size())+count(k) size_type count(const key_type& x) const - { return m_tree.find(x) == m_tree.end() ? 0 : 1; } + { return static_cast(m_tree.find(x) != m_tree.end()); } //! Returns: An iterator pointing to the first element with key not less //! than k, or a.end() if such an element is not found. @@ -918,8 +930,7 @@ class multimap BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } - //! Effects: Constructs an empty multimap using the specified comparison - //! object and allocator. + //! Effects: Constructs an empty multimap using the specified allocator. //! //! Complexity: Constant. explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) @@ -929,6 +940,17 @@ class multimap BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); } + //! Effects: Constructs an empty multimap using the specified comparison + //! object and allocator. + //! + //! Complexity: Constant. + explicit multimap(const allocator_type& a) + : m_tree(a) + { + //Allocator type must be std::pair + BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); + } + //! Effects: Constructs an empty multimap using the specified comparison object //! and allocator, and inserts elements from the range [first ,last ). //! @@ -951,6 +973,8 @@ class multimap //! Requires: [first ,last) must be ordered according to the predicate. //! //! Complexity: Linear in N. + //! + //! Note: Non-standard extension. template multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) diff --git a/cpp/BoostParts/boost/container/scoped_allocator.hpp b/cpp/BoostParts/boost/container/scoped_allocator.hpp index f9f21087..d16ac37f 100644 --- a/cpp/BoostParts/boost/container/scoped_allocator.hpp +++ b/cpp/BoostParts/boost/container/scoped_allocator.hpp @@ -17,7 +17,7 @@ #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP -#if (defined MSC_VER) && (_MSC_VER >= 1200) +#if defined (_MSC_VER) # pragma once #endif @@ -583,8 +583,10 @@ class scoped_allocator_adaptor_base }; typedef OuterAlloc outer_allocator_type; - typedef scoped_allocator_adaptor inner_allocator_type; - typedef allocator_traits inner_traits_type; + typedef scoped_allocator_adaptor inner_allocator_type; + typedef allocator_traits inner_traits_type; + typedef scoped_allocator_adaptor + scoped_allocator_type; typedef boost::integral_constant< bool, outer_traits_type::propagate_on_container_copy_assignment::value || @@ -635,7 +637,7 @@ class scoped_allocator_adaptor_base , m_inner(other.inner_allocator()) {} - protected: + public: struct internal_type_t{}; template @@ -670,6 +672,9 @@ class scoped_allocator_adaptor_base boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); } + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + { l.swap(r); } + inner_allocator_type& inner_allocator() { return m_inner; } @@ -682,6 +687,15 @@ class scoped_allocator_adaptor_base const outer_allocator_type &outer_allocator() const { return static_cast(*this); } + scoped_allocator_type select_on_container_copy_construction() const + { + return scoped_allocator_type + (internal_type_t() + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) + ); + } + private: inner_allocator_type m_inner; }; @@ -730,6 +744,11 @@ class scoped_allocator_adaptor_base inner_allocator_type; \ + typedef scoped_allocator_adaptor scoped_allocator_type; \ typedef allocator_traits inner_traits_type; \ typedef boost::integral_constant< \ bool, \ @@ -790,7 +809,7 @@ class scoped_allocator_adaptor_base \ @@ -824,6 +843,9 @@ class scoped_allocator_adaptor_basem_inner, r.inner_allocator()); \ } \ \ + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \ + { l.swap(r); } \ + \ inner_allocator_type& inner_allocator() \ { return m_inner; } \ \ @@ -836,6 +858,14 @@ class scoped_allocator_adaptor_base(*this); } \ \ + scoped_allocator_type select_on_container_copy_construction() const \ + { \ + return scoped_allocator_type \ + (internal_type_t() \ + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \ + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \ + ); \ + } \ private: \ inner_allocator_type m_inner; \ }; \ @@ -874,6 +904,7 @@ class scoped_allocator_adaptor_base typedef OuterAlloc outer_allocator_type; typedef allocator_traits outer_traits_type; typedef scoped_allocator_adaptor inner_allocator_type; + typedef inner_allocator_type scoped_allocator_type; typedef allocator_traits inner_traits_type; typedef typename outer_traits_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; @@ -922,7 +953,7 @@ class scoped_allocator_adaptor_base : outer_allocator_type(other.outer_allocator()) {} - protected: + public: struct internal_type_t{}; template @@ -948,6 +979,9 @@ class scoped_allocator_adaptor_base boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); } + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + { l.swap(r); } + inner_allocator_type& inner_allocator() { return static_cast(*this); } @@ -959,6 +993,17 @@ class scoped_allocator_adaptor_base const outer_allocator_type &outer_allocator() const { return static_cast(*this); } + + scoped_allocator_type select_on_container_copy_construction() const + { + return scoped_allocator_type + (internal_type_t() + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) + //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) + //as inner_allocator() is equal to *this and that would trigger an infinite loop + , this->inner_allocator() + ); + } }; } //namespace container_detail { @@ -1040,7 +1085,7 @@ class scoped_allocator_adaptor , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) #endif > base_type; - typedef typename base_type::internal_type_t internal_type_t; + typedef typename base_type::internal_type_t internal_type_t; /// @endcond typedef OuterAlloc outer_allocator_type; //! Type: For exposition only @@ -1164,48 +1209,37 @@ class scoped_allocator_adaptor {} scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) - { - base_type::operator=(static_cast(other)); - return *this; - } + { return static_cast(base_type::operator=(static_cast(other))); } scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) - { - base_type::operator=(boost::move(static_cast(other))); - return *this; - } + { return static_cast(base_type::operator=(boost::move(static_cast(other)))); } + + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: swaps *this with r. + //! + void swap(scoped_allocator_adaptor &r); //! Effects: swaps *this with r. //! - void swap(scoped_allocator_adaptor &r) - { - base_type::swap(r); - } - - //! Effects: swaps *this with r. - //! - friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r) - { l.swap(r); } + friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r); //! Returns: //! `static_cast(*this)`. - outer_allocator_type & outer_allocator() - { return *this; } + outer_allocator_type & outer_allocator(); //! Returns: //! `static_cast(*this)`. - const outer_allocator_type &outer_allocator() const - { return *this; } + const outer_allocator_type &outer_allocator() const; //! Returns: //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. - inner_allocator_type& inner_allocator() - { return base_type::inner_allocator(); } + inner_allocator_type& inner_allocator(); //! Returns: //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. - inner_allocator_type const& inner_allocator() const - { return base_type::inner_allocator(); } + inner_allocator_type const& inner_allocator() const; + + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: //! `allocator_traits::max_size(outer_allocator())`. @@ -1244,18 +1278,14 @@ class scoped_allocator_adaptor outer_traits_type::deallocate(this->outer_allocator(), p, n); } + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: Allocator new scoped_allocator_adaptor object where each allocator //! A in the adaptor is initialized from the result of calling //! `allocator_traits::select_on_container_copy_construction()` on //! the corresponding allocator in *this. - scoped_allocator_adaptor select_on_container_copy_construction() const - { - return scoped_allocator_adaptor - (internal_type_t() - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) - ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) - ); - } + scoped_allocator_adaptor select_on_container_copy_construction() const; + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED + /// @cond base_type &base() { return *this; } @@ -1426,7 +1456,8 @@ class scoped_allocator_adaptor //template //void construct(pair* p, piecewise_construct_t, tuple x, tuple y); - private: + public: + //Internal function template scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) : base_type(internal_type_t(), ::boost::forward(outer), inner) diff --git a/cpp/BoostParts/boost/container/scoped_allocator_fwd.hpp b/cpp/BoostParts/boost/container/scoped_allocator_fwd.hpp index ef247993..4c066b0a 100644 --- a/cpp/BoostParts/boost/container/scoped_allocator_fwd.hpp +++ b/cpp/BoostParts/boost/container/scoped_allocator_fwd.hpp @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP -#if (defined MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/container/throw_exception.hpp b/cpp/BoostParts/boost/container/throw_exception.hpp index e22d1042..7c821c0b 100644 --- a/cpp/BoostParts/boost/container/throw_exception.hpp +++ b/cpp/BoostParts/boost/container/throw_exception.hpp @@ -14,7 +14,7 @@ #include #include -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif diff --git a/cpp/BoostParts/boost/cstdint.hpp b/cpp/BoostParts/boost/cstdint.hpp index d466ae5f..98faeae0 100644 --- a/cpp/BoostParts/boost/cstdint.hpp +++ b/cpp/BoostParts/boost/cstdint.hpp @@ -1,8 +1,8 @@ // boost cstdint.hpp header file ------------------------------------------// -// (C) Copyright Beman Dawes 1999. -// (C) Copyright Jens Mauer 2001 -// (C) Copyright John Maddock 2001 +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 2001 // 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) @@ -24,9 +24,9 @@ #define BOOST_CSTDINT_HPP // -// Since we always define the INT#_C macros as per C++0x, +// Since we always define the INT#_C macros as per C++0x, // define __STDC_CONSTANT_MACROS so that does the right -// thing if possible, and so that the user knows that the macros +// thing if possible, and so that the user knows that the macros // are actually defined as per C99. // #ifndef __STDC_CONSTANT_MACROS @@ -53,7 +53,7 @@ # ifdef __STDC_32_MODE__ // this is triggered with GCC, because it defines __cplusplus < 199707L # define BOOST_NO_INT64_T -# endif +# endif # elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) # include # else @@ -103,40 +103,40 @@ typedef ::uintfast64_t uint_fast64_t; namespace boost { - using ::int8_t; - using ::int_least8_t; - using ::int_fast8_t; - using ::uint8_t; - using ::uint_least8_t; - using ::uint_fast8_t; - - using ::int16_t; - using ::int_least16_t; - using ::int_fast16_t; - using ::uint16_t; - using ::uint_least16_t; - using ::uint_fast16_t; - - using ::int32_t; - using ::int_least32_t; - using ::int_fast32_t; - using ::uint32_t; - using ::uint_least32_t; - using ::uint_fast32_t; - + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + # ifndef BOOST_NO_INT64_T - using ::int64_t; - using ::int_least64_t; - using ::int_fast64_t; - using ::uint64_t; - using ::uint_least64_t; - using ::uint_fast64_t; - + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + # endif - using ::intmax_t; - using ::uintmax_t; + using ::intmax_t; + using ::uintmax_t; } // namespace boost @@ -146,35 +146,35 @@ namespace boost namespace boost { - using ::int8_t; - typedef int8_t int_least8_t; - typedef int8_t int_fast8_t; - using ::uint8_t; - typedef uint8_t uint_least8_t; - typedef uint8_t uint_fast8_t; - - using ::int16_t; - typedef int16_t int_least16_t; - typedef int16_t int_fast16_t; - using ::uint16_t; - typedef uint16_t uint_least16_t; - typedef uint16_t uint_fast16_t; - - using ::int32_t; - typedef int32_t int_least32_t; - typedef int32_t int_fast32_t; - using ::uint32_t; - typedef uint32_t uint_least32_t; - typedef uint32_t uint_fast32_t; - -# ifndef BOOST_NO_INT64_T + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; - using ::int64_t; - typedef int64_t int_least64_t; - typedef int64_t int_fast64_t; - using ::uint64_t; - typedef uint64_t uint_least64_t; - typedef uint64_t uint_fast64_t; + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; typedef int64_t intmax_t; typedef uint64_t uintmax_t; @@ -238,15 +238,15 @@ namespace boost typedef unsigned short uint_least16_t; typedef unsigned short uint_fast16_t; # endif -# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) - // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified - // MTA / XMT does support the following non-standard integer types - typedef __short16 int16_t; - typedef __short16 int_least16_t; - typedef __short16 int_fast16_t; - typedef unsigned __short16 uint16_t; - typedef unsigned __short16 uint_least16_t; - typedef unsigned __short16 uint_fast16_t; +# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) + // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified + // MTA / XMT does support the following non-standard integer types + typedef __short16 int16_t; + typedef __short16 int_least16_t; + typedef __short16 int_fast16_t; + typedef unsigned __short16 uint16_t; + typedef unsigned __short16 uint_least16_t; + typedef unsigned __short16 uint_fast16_t; # elif (USHRT_MAX == 0xffffffff) && defined(CRAY) // no 16-bit types on Cray: typedef short int_least16_t; @@ -280,14 +280,14 @@ namespace boost typedef unsigned long uint32_t; typedef unsigned long uint_least32_t; typedef unsigned long uint_fast32_t; -# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) - // Integers are 64 bits on the MTA / XMT - typedef __int32 int32_t; - typedef __int32 int_least32_t; - typedef __int32 int_fast32_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int32 uint_least32_t; - typedef unsigned __int32 uint_fast32_t; +# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) + // Integers are 64 bits on the MTA / XMT + typedef __int32 int32_t; + typedef __int32 int_least32_t; + typedef __int32 int_fast32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int32 uint_fast32_t; # else # error defaults not correct; you must hand modify boost/cstdint.hpp # endif @@ -361,6 +361,40 @@ namespace boost #endif // BOOST_HAS_STDINT_H +// intptr_t/uintptr_t are defined separately because they are optional and not universally available +#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) +// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h +#include +#endif + +// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config. +#if !defined(__PGIC__) + +#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ + || defined(__CYGWIN__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ + || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + +namespace boost { + using ::intptr_t; + using ::uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +// Clang pretends to be GCC, so it'll match this condition +#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) + +namespace boost { + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +#endif + +#endif // !defined(__PGIC__) + #endif // BOOST_CSTDINT_HPP @@ -379,15 +413,15 @@ INT#_C macros if they're not already defined (John Maddock). #if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) // -// For the following code we get several warnings along the lines of: -// -// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant -// -// So we declare this a system header to suppress these warnings. +// For the following code we get several warnings along the lines of: // -#if defined(__GNUC__) && (__GNUC__ >= 4) -#pragma GCC system_header -#endif +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif #include # define BOOST__STDC_CONSTANT_MACROS_DEFINED diff --git a/cpp/BoostParts/boost/date_time/format_date_parser.hpp b/cpp/BoostParts/boost/date_time/format_date_parser.hpp index 3f647675..1a69055c 100644 --- a/cpp/BoostParts/boost/date_time/format_date_parser.hpp +++ b/cpp/BoostParts/boost/date_time/format_date_parser.hpp @@ -7,7 +7,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2013-06-21 08:04:12 -0700 (Fri, 21 Jun 2013) $ + * $Date: 2013-10-15 08:22:02 -0700 (Tue, 15 Oct 2013) $ */ @@ -271,7 +271,8 @@ class format_date_parser const_itr itr(format_str.begin()); while (itr != format_str.end() && (sitr != stream_end)) { if (*itr == '%') { - itr++; + if ( ++itr == format_str.end()) + break; if (*itr != '%') { switch(*itr) { case 'a': @@ -476,7 +477,8 @@ class format_date_parser const_itr itr(format_str.begin()); while (itr != format_str.end() && (sitr != stream_end)) { if (*itr == '%') { - itr++; + if ( ++itr == format_str.end()) + break; if (*itr != '%') { switch(*itr) { case 'b': @@ -577,7 +579,8 @@ class format_date_parser const_itr itr(format_str.begin()); while (itr != format_str.end() && (sitr != stream_end)) { if (*itr == '%') { - itr++; + if ( ++itr == format_str.end()) + break; if (*itr != '%') { switch(*itr) { case 'a': @@ -666,7 +669,8 @@ class format_date_parser const_itr itr(format_str.begin()); while (itr != format_str.end() && (sitr != stream_end)) { if (*itr == '%') { - itr++; + if ( ++itr == format_str.end()) + break; if (*itr != '%') { //match_results mr; switch(*itr) { diff --git a/cpp/BoostParts/boost/date_time/strings_from_facet.hpp b/cpp/BoostParts/boost/date_time/strings_from_facet.hpp index 82da517c..ccc78ef0 100644 --- a/cpp/BoostParts/boost/date_time/strings_from_facet.hpp +++ b/cpp/BoostParts/boost/date_time/strings_from_facet.hpp @@ -6,7 +6,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland - * $Date: 2013-06-21 08:04:12 -0700 (Fri, 21 Jun 2013) $ + * $Date: 2013-09-21 13:17:00 -0700 (Sat, 21 Sep 2013) $ */ #include diff --git a/cpp/BoostParts/boost/detail/endian.hpp b/cpp/BoostParts/boost/detail/endian.hpp index 3236808d..3e37db93 100644 --- a/cpp/BoostParts/boost/detail/endian.hpp +++ b/cpp/BoostParts/boost/detail/endian.hpp @@ -1,126 +1,11 @@ -// Copyright 2005 Caleb Epstein -// Copyright 2006 John Maddock -// Copyright 2010 Rene Rivera +// Copyright 2013 Redshift Software Inc // Distributed under the Boost Software License, Version 1.0. (See accompany- // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -/* - * Copyright (c) 1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - */ - -/* - * Copyright notice reproduced from , from - * which this code was originally taken. - * - * Modified by Caleb Epstein to use with GNU libc and to - * defined the BOOST_ENDIAN macro. - */ - #ifndef BOOST_DETAIL_ENDIAN_HPP #define BOOST_DETAIL_ENDIAN_HPP -// -// Special cases come first: -// -#if defined (__GLIBC__) -// GNU libc offers the helpful header which defines -// __BYTE_ORDER -# include -# if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define BOOST_LITTLE_ENDIAN -# elif (__BYTE_ORDER == __BIG_ENDIAN) -# define BOOST_BIG_ENDIAN -# elif (__BYTE_ORDER == __PDP_ENDIAN) -# define BOOST_PDP_ENDIAN -# else -# error Unknown machine endianness detected. -# endif -# define BOOST_BYTE_ORDER __BYTE_ORDER - -#elif defined(__NetBSD__) || defined(__FreeBSD__) || \ - defined(__OpenBSD__) || (__DragonFly__) -// -// BSD has endian.h, see https://svn.boost.org/trac/boost/ticket/6013 -# if defined(__OpenBSD__) -# include -# else -# include -# endif -# if (_BYTE_ORDER == _LITTLE_ENDIAN) -# define BOOST_LITTLE_ENDIAN -# elif (_BYTE_ORDER == _BIG_ENDIAN) -# define BOOST_BIG_ENDIAN -# elif (_BYTE_ORDER == _PDP_ENDIAN) -# define BOOST_PDP_ENDIAN -# else -# error Unknown machine endianness detected. -# endif -# define BOOST_BYTE_ORDER _BYTE_ORDER - -#elif defined( __ANDROID__ ) -// Adroid specific code, see: https://svn.boost.org/trac/boost/ticket/7528 -// Here we can use machine/_types.h, see: -// http://stackoverflow.com/questions/6212951/endianness-of-android-ndk -# include "machine/_types.h" -# ifdef __ARMEB__ -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 -# else -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 -# endif // __ARMEB__ - -#elif defined( _XBOX ) -// -// XBox is always big endian?? -// -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 - -#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || \ - defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) || \ - defined(__BIGENDIAN__) && !defined(__LITTLEENDIAN__) || \ - defined(_STLP_BIG_ENDIAN) && !defined(_STLP_LITTLE_ENDIAN) -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 -#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || \ - defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) || \ - defined(__LITTLEENDIAN__) && !defined(__BIGENDIAN__) || \ - defined(_STLP_LITTLE_ENDIAN) && !defined(_STLP_BIG_ENDIAN) -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 -#elif defined(__sparc) || defined(__sparc__) \ - || defined(_POWER) || defined(__powerpc__) \ - || defined(__ppc__) || defined(__hpux) || defined(__hppa) \ - || defined(_MIPSEB) || defined(_POWER) \ - || defined(__s390__) || defined(__ARMEB__) -# define BOOST_BIG_ENDIAN -# define BOOST_BYTE_ORDER 4321 -#elif defined(__i386__) || defined(__alpha__) \ - || defined(__ia64) || defined(__ia64__) \ - || defined(_M_IX86) || defined(_M_IA64) \ - || defined(_M_ALPHA) || defined(__amd64) \ - || defined(__amd64__) || defined(_M_AMD64) \ - || defined(__x86_64) || defined(__x86_64__) \ - || defined(_M_X64) || defined(__bfin__) \ - || defined(__ARMEL__) \ - || (defined(_WIN32) && defined(__ARM__) && defined(_MSC_VER)) // ARM Windows CE don't define anything reasonably unique, but there are no big-endian Windows versions - -# define BOOST_LITTLE_ENDIAN -# define BOOST_BYTE_ORDER 1234 -#else -# error The file boost/detail/endian.hpp needs to be set up for your CPU type. -#endif - +// Use the Predef library for the detection of endianess. +#include #endif - diff --git a/cpp/BoostParts/boost/detail/interlocked.hpp b/cpp/BoostParts/boost/detail/interlocked.hpp index 75e5a306..1152f710 100644 --- a/cpp/BoostParts/boost/detail/interlocked.hpp +++ b/cpp/BoostParts/boost/detail/interlocked.hpp @@ -1,12 +1,6 @@ #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED #define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - // // boost/detail/interlocked.hpp // @@ -19,6 +13,11 @@ #include +// MS compatible compilers support #pragma once +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + #if defined( BOOST_USE_WINDOWS_H ) # include @@ -31,6 +30,30 @@ # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer +#elif defined( BOOST_USE_INTRIN_H ) + +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +# if defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + #elif defined(_WIN32_WCE) #if _WIN32_WCE >= 0x600 @@ -71,7 +94,7 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) -#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1500 #include @@ -93,20 +116,11 @@ extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); #endif -# pragma intrinsic( _InterlockedIncrement ) -# pragma intrinsic( _InterlockedDecrement ) -# pragma intrinsic( _InterlockedCompareExchange ) -# pragma intrinsic( _InterlockedExchange ) -# pragma intrinsic( _InterlockedExchangeAdd ) - # if defined(_M_IA64) || defined(_M_AMD64) extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); -# pragma intrinsic( _InterlockedCompareExchangePointer ) -# pragma intrinsic( _InterlockedExchangePointer ) - # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer @@ -125,14 +139,30 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined(__MINGW64_VERSION_MAJOR) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd +# if defined(__x86_64__) || defined(__x86_64) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) +# endif + #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) -#if defined(__MINGW64__) -#define BOOST_INTERLOCKED_IMPORT -#else #define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) -#endif - namespace boost { diff --git a/cpp/BoostParts/boost/detail/win/GetLastError.hpp b/cpp/BoostParts/boost/detail/winapi/GetLastError.hpp similarity index 63% rename from cpp/BoostParts/boost/detail/win/GetLastError.hpp rename to cpp/BoostParts/boost/detail/winapi/GetLastError.hpp index d040abf5..6e9e2d99 100644 --- a/cpp/BoostParts/boost/detail/win/GetLastError.hpp +++ b/cpp/BoostParts/boost/detail/winapi/GetLastError.hpp @@ -6,14 +6,18 @@ // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DETAIL_WIN_GETLASTERROR_HPP -#define BOOST_DETAIL_WIN_GETLASTERROR_HPP +#ifndef BOOST_DETAIL_WINAPI_GETLASTERROR_HPP +#define BOOST_DETAIL_WINAPI_GETLASTERROR_HPP -#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif namespace boost { namespace detail { -namespace win32 { +namespace winapi { #if defined( BOOST_USE_WINDOWS_H ) using ::GetLastError; #else @@ -24,4 +28,4 @@ namespace win32 { } } -#endif // BOOST_DETAIL_WIN_TIME_HPP +#endif // BOOST_DETAIL_WINAPI_GETLASTERROR_HPP diff --git a/cpp/BoostParts/boost/detail/win/basic_types.hpp b/cpp/BoostParts/boost/detail/winapi/basic_types.hpp similarity index 91% rename from cpp/BoostParts/boost/detail/win/basic_types.hpp rename to cpp/BoostParts/boost/detail/winapi/basic_types.hpp index f4e34721..e9ca3700 100644 --- a/cpp/BoostParts/boost/detail/win/basic_types.hpp +++ b/cpp/BoostParts/boost/detail/winapi/basic_types.hpp @@ -6,15 +6,17 @@ // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DETAIL_WIN_BASIC_TYPES_HPP -#define BOOST_DETAIL_WIN_BASIC_TYPES_HPP +#ifndef BOOST_DETAIL_WINAPI_BASIC_TYPES_HPP +#define BOOST_DETAIL_WINAPI_BASIC_TYPES_HPP + #include #include #include + #if defined( BOOST_USE_WINDOWS_H ) # include #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) -# include +# include // @FIXME Which condition must be tested # ifdef UNDER_CE # ifndef WINAPI @@ -33,9 +35,13 @@ # error "Win32 functions not available" #endif +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + namespace boost { namespace detail { -namespace win32 { +namespace winapi { #if defined( BOOST_USE_WINDOWS_H ) typedef ::BOOL BOOL_; typedef ::WORD WORD_; @@ -102,10 +108,9 @@ extern "C" { typedef wchar_t WCHAR_; typedef WCHAR_ *LPWSTR_; typedef const WCHAR_ *LPCWSTR_; - } #endif } } } -#endif // BOOST_DETAIL_WIN_TIME_HPP +#endif // BOOST_DETAIL_WINAPI_TIME_HPP diff --git a/cpp/BoostParts/boost/detail/win/time.hpp b/cpp/BoostParts/boost/detail/winapi/time.hpp similarity index 64% rename from cpp/BoostParts/boost/detail/win/time.hpp rename to cpp/BoostParts/boost/detail/winapi/time.hpp index 7f636edb..b3e4c441 100644 --- a/cpp/BoostParts/boost/detail/win/time.hpp +++ b/cpp/BoostParts/boost/detail/winapi/time.hpp @@ -6,15 +6,18 @@ // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DETAIL_WIN_TIME_HPP -#define BOOST_DETAIL_WIN_TIME_HPP +#ifndef BOOST_DETAIL_WINAPI_TIME_HPP +#define BOOST_DETAIL_WINAPI_TIME_HPP -#include +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif namespace boost { namespace detail { -namespace win32 { +namespace winapi { #if defined( BOOST_USE_WINDOWS_H ) typedef FILETIME FILETIME_; typedef PFILETIME PFILETIME_; @@ -23,7 +26,7 @@ namespace win32 { typedef SYSTEMTIME SYSTEMTIME_; typedef SYSTEMTIME* PSYSTEMTIME_; - #ifndef UNDER_CE // Windows CE does not define GetSystemTimeAsFileTime + #ifdef BOOST_HAS_GETSYSTEMTIMEASFILETIME // Windows CE does not define GetSystemTimeAsFileTime using ::GetSystemTimeAsFileTime; #endif using ::FileTimeToLocalFileTime; @@ -49,24 +52,34 @@ extern "C" { WORD_ wMilliseconds; } SYSTEMTIME_, *PSYSTEMTIME_; - #ifndef UNDER_CE // Windows CE does not define GetSystemTimeAsFileTime + #ifdef BOOST_HAS_GETSYSTEMTIMEASFILETIME // Windows CE does not define GetSystemTimeAsFileTime __declspec(dllimport) void WINAPI GetSystemTimeAsFileTime(FILETIME_* lpFileTime); #endif __declspec(dllimport) int WINAPI - FileTimeToLocalFileTime(const FILETIME_* lpFileTime, + FileTimeToLocalFileTime(const FILETIME_* lpFileTime, FILETIME_* lpLocalFileTime); __declspec(dllimport) void WINAPI GetSystemTime(SYSTEMTIME_* lpSystemTime); __declspec(dllimport) int WINAPI - SystemTimeToFileTime(const SYSTEMTIME_* lpSystemTime, + SystemTimeToFileTime(const SYSTEMTIME_* lpSystemTime, FILETIME_* lpFileTime); - __declspec(dllimport) unsigned long __stdcall + __declspec(dllimport) DWORD_ WINAPI GetTickCount(); } #endif + +#ifndef BOOST_HAS_GETSYSTEMTIMEASFILETIME +inline void WINAPI GetSystemTimeAsFileTime(FILETIME_* lpFileTime) +{ + SYSTEMTIME_ st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, lpFileTime); +} +#endif + } } } -#endif // BOOST_DETAIL_WIN_TIME_HPP +#endif // BOOST_DETAIL_WINAPI_TIME_HPP diff --git a/cpp/BoostParts/boost/detail/win/timers.hpp b/cpp/BoostParts/boost/detail/winapi/timers.hpp similarity index 74% rename from cpp/BoostParts/boost/detail/win/timers.hpp rename to cpp/BoostParts/boost/detail/winapi/timers.hpp index 753c91f8..04c6dfbc 100644 --- a/cpp/BoostParts/boost/detail/win/timers.hpp +++ b/cpp/BoostParts/boost/detail/winapi/timers.hpp @@ -6,17 +6,20 @@ // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_DETAIL_WIN_TIMERS_HPP -#define BOOST_DETAIL_WIN_TIMERS_HPP +#ifndef BOOST_DETAIL_WINAPI_TIMERS_HPP +#define BOOST_DETAIL_WINAPI_TIMERS_HPP -#include +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif namespace boost { namespace detail { -namespace win32 +namespace winapi { #if defined( BOOST_USE_WINDOWS_H ) using ::QueryPerformanceCounter; @@ -38,4 +41,4 @@ extern "C" { } } -#endif // BOOST_DETAIL_WIN_TIMERS_HPP +#endif // BOOST_DETAIL_WINAPI_TIMERS_HPP diff --git a/cpp/BoostParts/boost/exception/detail/clone_current_exception.hpp b/cpp/BoostParts/boost/exception/detail/clone_current_exception.hpp index cc201b90..6fc13747 100644 --- a/cpp/BoostParts/boost/exception/detail/clone_current_exception.hpp +++ b/cpp/BoostParts/boost/exception/detail/clone_current_exception.hpp @@ -1,10 +1,16 @@ -//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. +//Copyright (c) 2006-2013 Emil Dotchevski and Reverge Studios, Inc. //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 UUID_81522C0EB56511DFAB613DB0DFD72085 #define UUID_81522C0EB56511DFAB613DB0DFD72085 +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif #ifdef BOOST_NO_EXCEPTIONS # error This header requires exception handling to be enabled. @@ -44,4 +50,7 @@ boost } } +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif #endif diff --git a/cpp/BoostParts/boost/exception/detail/exception_ptr.hpp b/cpp/BoostParts/boost/exception/detail/exception_ptr.hpp index b2ee3656..36298fa4 100644 --- a/cpp/BoostParts/boost/exception/detail/exception_ptr.hpp +++ b/cpp/BoostParts/boost/exception/detail/exception_ptr.hpp @@ -21,6 +21,9 @@ #include #include #include +//#ifndef BOOST_NO_RTTI +//#include +//#endif #include #include #include @@ -89,7 +92,7 @@ boost std::string to_string( original_exception_type const & x ) { - return x.value()->name(); + return /*units::detail::demangle*/(x.value()->name()); } #endif @@ -118,10 +121,12 @@ boost { Exception ba; exception_detail::clone_impl c(ba); +#ifndef BOOST_EXCEPTION_DISABLE c << throw_function(BOOST_CURRENT_FUNCTION) << throw_file(__FILE__) << throw_line(__LINE__); +#endif static exception_ptr ep(shared_ptr(new exception_detail::clone_impl(c))); return ep; } diff --git a/cpp/BoostParts/boost/exception/detail/type_info.hpp b/cpp/BoostParts/boost/exception/detail/type_info.hpp index 15fa1c49..0af8ef52 100644 --- a/cpp/BoostParts/boost/exception/detail/type_info.hpp +++ b/cpp/BoostParts/boost/exception/detail/type_info.hpp @@ -15,9 +15,9 @@ #include #include #include -#ifndef BOOST_NO_TYPEID -#include -#endif +//#ifndef BOOST_NO_TYPEID +//#include +//#endif #include namespace @@ -31,7 +31,7 @@ boost #ifdef BOOST_NO_TYPEID return BOOST_CURRENT_FUNCTION; #else - return units::detail::demangle(typeid(T*).name()); + return /*units::detail::demangle*/(typeid(T*).name()); #endif } @@ -43,7 +43,7 @@ boost #ifdef BOOST_NO_TYPEID return BOOST_CURRENT_FUNCTION; #else - return units::detail::demangle(typeid(T).name()); + return /*units::detail::demangle*/(typeid(T).name()); #endif } diff --git a/cpp/BoostParts/boost/exception/diagnostic_information.hpp b/cpp/BoostParts/boost/exception/diagnostic_information.hpp index 5ac8c6b1..7889c8f9 100644 --- a/cpp/BoostParts/boost/exception/diagnostic_information.hpp +++ b/cpp/BoostParts/boost/exception/diagnostic_information.hpp @@ -16,9 +16,9 @@ #include #include #include -#ifndef BOOST_NO_RTTI -#include -#endif +//#ifndef BOOST_NO_RTTI +//#include +//#endif #include #include #include @@ -151,7 +151,7 @@ boost #ifndef BOOST_NO_RTTI if ( verbose ) tmp << std::string("Dynamic exception type: ") << - units::detail::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n'; + /*units::detail::demangle*/((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n'; #endif if( with_what && se && verbose ) tmp << "std::exception::what: " << wh << '\n'; diff --git a/cpp/BoostParts/boost/functional/hash/detail/hash_float.hpp b/cpp/BoostParts/boost/functional/hash/detail/hash_float.hpp index a98cd700..7c3de31a 100644 --- a/cpp/BoostParts/boost/functional/hash/detail/hash_float.hpp +++ b/cpp/BoostParts/boost/functional/hash/detail/hash_float.hpp @@ -90,15 +90,21 @@ namespace boost return seed; } + template + struct enable_binary_hash + { + BOOST_STATIC_CONSTANT(bool, value = + std::numeric_limits::is_iec559 && + std::numeric_limits::digits == digits && + std::numeric_limits::radix == 2 && + std::numeric_limits::max_exponent == max_exponent); + }; + template inline std::size_t float_hash_impl(Float v, BOOST_DEDUCED_TYPENAME boost::enable_if_c< - std::numeric_limits::is_iec559 && - std::numeric_limits::digits == 24 && - std::numeric_limits::radix == 2 && - std::numeric_limits::max_exponent == 128, - int>::type - ) + enable_binary_hash::value, + std::size_t>::type) { return hash_binary((char*) &v, 4); } @@ -107,12 +113,8 @@ namespace boost template inline std::size_t float_hash_impl(Float v, BOOST_DEDUCED_TYPENAME boost::enable_if_c< - std::numeric_limits::is_iec559 && - std::numeric_limits::digits == 53 && - std::numeric_limits::radix == 2 && - std::numeric_limits::max_exponent == 1024, - int>::type - ) + enable_binary_hash::value, + std::size_t>::type) { return hash_binary((char*) &v, 8); } @@ -120,12 +122,8 @@ namespace boost template inline std::size_t float_hash_impl(Float v, BOOST_DEDUCED_TYPENAME boost::enable_if_c< - std::numeric_limits::is_iec559 && - std::numeric_limits::digits == 64 && - std::numeric_limits::radix == 2 && - std::numeric_limits::max_exponent == 16384, - int>::type - ) + enable_binary_hash::value, + std::size_t>::type) { return hash_binary((char*) &v, 10); } @@ -133,12 +131,8 @@ namespace boost template inline std::size_t float_hash_impl(Float v, BOOST_DEDUCED_TYPENAME boost::enable_if_c< - std::numeric_limits::is_iec559 && - std::numeric_limits::digits == 113 && - std::numeric_limits::radix == 2 && - std::numeric_limits::max_exponent == 16384, - int>::type - ) + enable_binary_hash::value, + std::size_t>::type) { return hash_binary((char*) &v, 16); } diff --git a/cpp/BoostParts/boost/functional/hash/hash.hpp b/cpp/BoostParts/boost/functional/hash/hash.hpp index aa4e49f8..0adf9c90 100644 --- a/cpp/BoostParts/boost/functional/hash/hash.hpp +++ b/cpp/BoostParts/boost/functional/hash/hash.hpp @@ -27,6 +27,13 @@ #include #endif +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values + // are always of range '0' to '4294967295'. + // Loop executes infinitely. +#endif + #if BOOST_WORKAROUND(__GNUC__, < 3) \ && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) #define BOOST_HASH_CHAR_TRAITS string_char_traits @@ -518,6 +525,10 @@ namespace boost #undef BOOST_HASH_CHAR_TRAITS +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + #endif // BOOST_FUNCTIONAL_HASH_HASH_HPP // Include this outside of the include guards in case the file is included diff --git a/cpp/BoostParts/boost/graph/breadth_first_search.hpp b/cpp/BoostParts/boost/graph/breadth_first_search.hpp index 18bc24f5..b0d10ad5 100644 --- a/cpp/BoostParts/boost/graph/breadth_first_search.hpp +++ b/cpp/BoostParts/boost/graph/breadth_first_search.hpp @@ -64,7 +64,6 @@ namespace boost { BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); typedef graph_traits GTraits; typedef typename GTraits::vertex_descriptor Vertex; - typedef typename GTraits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( BFSVisitorConcept )); BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept )); typedef typename property_traits::value_type ColorValue; @@ -248,8 +247,7 @@ namespace boost { ColorMap color, BFSVisitor vis, const bgl_named_params& params, - BOOST_GRAPH_ENABLE_IF_MODELS(VertexListGraph, vertex_list_graph_tag, - void)* = 0) + boost::mpl::false_) { typedef graph_traits Traits; // Buffer default @@ -271,8 +269,7 @@ namespace boost { ColorMap color, BFSVisitor vis, const bgl_named_params& params, - BOOST_GRAPH_ENABLE_IF_MODELS(DistributedGraph, distributed_graph_tag, - void)* = 0); + boost::mpl::true_); #endif // BOOST_GRAPH_USE_MPI //------------------------------------------------------------------------- @@ -293,7 +290,11 @@ namespace boost { (g, s, color, choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_visitor())), - params); + params, + boost::mpl::bool_< + boost::is_base_and_derived< + distributed_graph_tag, + typename graph_traits::traversal_category>::value>()); } }; @@ -316,7 +317,11 @@ namespace boost { g, vertex_index)), choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_vis)), - params); + params, + boost::mpl::bool_< + boost::is_base_and_derived< + distributed_graph_tag, + typename graph_traits::traversal_category>::value>()); } }; diff --git a/cpp/BoostParts/boost/graph/detail/adjacency_list.hpp b/cpp/BoostParts/boost/graph/detail/adjacency_list.hpp index dd27ecd4..a99ec265 100644 --- a/cpp/BoostParts/boost/graph/detail/adjacency_list.hpp +++ b/cpp/BoostParts/boost/graph/detail/adjacency_list.hpp @@ -806,7 +806,6 @@ namespace boost { typedef typename EdgeList::value_type StoredEdge; typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end(); - BOOST_ASSERT ((i != end)); if (i != end) { g.m_edges.erase((*i).get_iter()); el.erase(i); diff --git a/cpp/BoostParts/boost/graph/distributed/breadth_first_search.hpp b/cpp/BoostParts/boost/graph/distributed/breadth_first_search.hpp index 36e2df8b..5bb99c6c 100644 --- a/cpp/BoostParts/boost/graph/distributed/breadth_first_search.hpp +++ b/cpp/BoostParts/boost/graph/distributed/breadth_first_search.hpp @@ -151,8 +151,7 @@ namespace boost { ColorMap color, BFSVisitor vis, const bgl_named_params& params, - BOOST_GRAPH_ENABLE_IF_MODELS(DistributedGraph, distributed_graph_tag, - void)*) + boost::mpl::true_) { parallel_bfs_helper (g, s, color, vis, get_param(params, buffer_param_t()), diff --git a/cpp/BoostParts/boost/graph/distributed/concepts.hpp b/cpp/BoostParts/boost/graph/distributed/concepts.hpp index 1c85b447..9d6e2672 100644 --- a/cpp/BoostParts/boost/graph/distributed/concepts.hpp +++ b/cpp/BoostParts/boost/graph/distributed/concepts.hpp @@ -29,10 +29,6 @@ namespace boost { -class distributed_graph_tag { }; -class distributed_vertex_list_graph_tag { }; -class distributed_edge_list_graph_tag { }; - #if BOOST_VERSION >= 103500 namespace concepts { #endif diff --git a/cpp/BoostParts/boost/graph/graph_traits.hpp b/cpp/BoostParts/boost/graph/graph_traits.hpp index ceb0c2ac..a1c27483 100644 --- a/cpp/BoostParts/boost/graph/graph_traits.hpp +++ b/cpp/BoostParts/boost/graph/graph_traits.hpp @@ -166,7 +166,13 @@ namespace boost { struct edge_list_graph_tag { }; struct adjacency_matrix_tag { }; - /** @name Taversal Category Traits + // Parallel traversal_category tags + struct distributed_graph_tag { }; + struct distributed_vertex_list_graph_tag { }; + struct distributed_edge_list_graph_tag { }; +#define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS // Disable these from external versions of PBGL + + /** @name Traversal Category Traits * These traits classify graph types by their supported methods of * vertex and edge traversal. */ diff --git a/cpp/BoostParts/boost/graph/named_function_params.hpp b/cpp/BoostParts/boost/graph/named_function_params.hpp index 4ab24f63..26d3d5e4 100644 --- a/cpp/BoostParts/boost/graph/named_function_params.hpp +++ b/cpp/BoostParts/boost/graph/named_function_params.hpp @@ -64,6 +64,7 @@ namespace boost { BOOST_BGL_ONE_PARAM_CREF(weight_map, edge_weight) \ BOOST_BGL_ONE_PARAM_CREF(weight_map2, edge_weight2) \ BOOST_BGL_ONE_PARAM_CREF(distance_map, vertex_distance) \ + BOOST_BGL_ONE_PARAM_CREF(distance_map2, vertex_distance2) \ BOOST_BGL_ONE_PARAM_CREF(predecessor_map, vertex_predecessor) \ BOOST_BGL_ONE_PARAM_CREF(rank_map, vertex_rank) \ BOOST_BGL_ONE_PARAM_CREF(root_map, vertex_root) \ diff --git a/cpp/BoostParts/boost/graph/visitors.hpp b/cpp/BoostParts/boost/graph/visitors.hpp index d10e140c..e4a614f3 100644 --- a/cpp/BoostParts/boost/graph/visitors.hpp +++ b/cpp/BoostParts/boost/graph/visitors.hpp @@ -44,7 +44,7 @@ namespace boost { on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num, on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num, on_gray_target_num, on_black_target_num, - on_forward_or_cross_edge_num, on_back_edge_num, + on_forward_or_cross_edge_num, on_back_edge_num, on_finish_edge_num, on_edge_relaxed_num, on_edge_not_relaxed_num, on_edge_minimized_num, on_edge_not_minimized_num }; @@ -75,6 +75,7 @@ namespace boost { struct on_forward_or_cross_edge { enum { num = detail::on_forward_or_cross_edge_num }; }; struct on_back_edge { enum { num = detail::on_back_edge_num }; }; + struct on_finish_edge { enum { num = detail::on_finish_edge_num }; }; struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; }; struct on_edge_not_relaxed { diff --git a/cpp/BoostParts/boost/integer_traits.hpp b/cpp/BoostParts/boost/integer_traits.hpp index f6272a48..d896e46e 100644 --- a/cpp/BoostParts/boost/integer_traits.hpp +++ b/cpp/BoostParts/boost/integer_traits.hpp @@ -5,7 +5,7 @@ * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * - * $Id: integer_traits.hpp 83381 2013-03-09 22:55:05Z eric_niebler $ + * $Id: integer_traits.hpp 85813 2013-09-21 20:17:00Z jewillco $ * * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers */ diff --git a/cpp/BoostParts/boost/interprocess/detail/atomic.hpp b/cpp/BoostParts/boost/interprocess/detail/atomic.hpp index 08481a43..fb56891e 100644 --- a/cpp/BoostParts/boost/interprocess/detail/atomic.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/atomic.hpp @@ -213,7 +213,7 @@ inline boost::uint32_t atomic_cas32 "bne- 1b\n\t" "2:" : "=&r"(prev) - : "b" (mem), "r"(cmp), "r" (with) + : "b" (mem), "r" (with), "r" (cmp) : "cc", "memory"); return prev; } diff --git a/cpp/BoostParts/boost/interprocess/detail/intermodule_singleton_common.hpp b/cpp/BoostParts/boost/interprocess/detail/intermodule_singleton_common.hpp index d03c5665..60ec5939 100644 --- a/cpp/BoostParts/boost/interprocess/detail/intermodule_singleton_common.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/intermodule_singleton_common.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -145,6 +146,7 @@ class intermodule_singleton_common //If previous state was initializing, this means that another winner thread is //trying to initialize the singleton. Just wait until completes its work. else if(previous_module_singleton_initialized == Initializing){ + spin_wait swait; while(1){ previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized); if(previous_module_singleton_initialized >= Initialized){ @@ -152,7 +154,7 @@ class intermodule_singleton_common break; } else if(previous_module_singleton_initialized == Initializing){ - thread_yield(); + swait.yield(); } else{ //This can't be happening! @@ -206,6 +208,7 @@ class intermodule_singleton_common static void initialize_global_map_handle() { //Obtain unique map name and size + spin_wait swait; while(1){ //Try to pass map state to initializing ::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized); @@ -218,7 +221,7 @@ class intermodule_singleton_common } //If some other thread is doing the work wait else if(tmp == Initializing){ - thread_yield(); + swait.yield(); } else{ //(tmp == Uninitialized) //If not initialized try it again? @@ -309,7 +312,7 @@ struct ref_count_ptr //Now this class is a singleton, initializing the singleton in -//the first get() function call if LazyInit is false. If true +//the first get() function call if LazyInit is true. If false //then the singleton will be initialized when loading the module. template class intermodule_singleton_impl diff --git a/cpp/BoostParts/boost/interprocess/detail/managed_open_or_create_impl.hpp b/cpp/BoostParts/boost/interprocess/detail/managed_open_or_create_impl.hpp index f8154d06..948b4f4b 100644 --- a/cpp/BoostParts/boost/interprocess/detail/managed_open_or_create_impl.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/managed_open_or_create_impl.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -354,6 +355,7 @@ class managed_open_or_create_impl //file and know if we have really created it or just open it //drop me a e-mail! bool completed = false; + spin_wait swait; while(!completed){ try{ create_device(dev, id, size, perm, file_like_t()); @@ -384,7 +386,7 @@ class managed_open_or_create_impl catch(...){ throw; } - thread_yield(); + swait.yield(); } } @@ -431,11 +433,12 @@ class managed_open_or_create_impl else{ if(FileBased){ offset_t filesize = 0; + spin_wait swait; while(filesize == 0){ if(!get_file_size(file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){ throw interprocess_exception(error_info(system_error_code())); } - thread_yield(); + swait.yield(); } if(filesize == 1){ throw interprocess_exception(error_info(corrupted_error)); @@ -447,8 +450,9 @@ class managed_open_or_create_impl boost::uint32_t *patomic_word = static_cast(region.get_address()); boost::uint32_t value = atomic_read32(patomic_word); + spin_wait swait; while(value == InitializingSegment || value == UninitializedSegment){ - thread_yield(); + swait.yield(); value = atomic_read32(patomic_word); } diff --git a/cpp/BoostParts/boost/interprocess/detail/os_thread_functions.hpp b/cpp/BoostParts/boost/interprocess/detail/os_thread_functions.hpp index f881a1f4..eea4957a 100644 --- a/cpp/BoostParts/boost/interprocess/detail/os_thread_functions.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/os_thread_functions.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-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) // @@ -8,6 +8,17 @@ // ////////////////////////////////////////////////////////////////////////////// +//Thread launching functions are adapted from boost/detail/lightweight_thread.hpp +// +// boost/detail/lightweight_thread.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008 Peter Dimov +// +// 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_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP #define BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP @@ -15,17 +26,38 @@ #include #include #include +#include +#include -#if (defined BOOST_INTERPROCESS_WINDOWS) +#if defined(BOOST_INTERPROCESS_WINDOWS) # include +# include #else -# ifdef BOOST_HAS_UNISTD_H -# include -# include -# include -# include +# include +# include +# include +# include +# ifdef BOOST_INTERPROCESS_BSD_DERIVATIVE + //Some *BSD systems (OpenBSD & NetBSD) need sys/param.h before sys/sysctl.h, whereas + //others (FreeBSD & Darwin) need sys/types.h +# include +# include +# include +# endif +//According to the article "C/C++ tip: How to measure elapsed real time for benchmarking" +# if defined(CLOCK_MONOTONIC_PRECISE) //BSD +# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE +# elif defined(CLOCK_MONOTONIC_RAW) //Linux +# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW +# elif defined(CLOCK_HIGHRES) //Solaris +# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES +# elif defined(CLOCK_MONOTONIC) //POSIX (AIX, BSD, Linux, Solaris) +# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC +# elif !defined(CLOCK_MONOTONIC) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +# include // mach_absolute_time, mach_timebase_info_data_t +# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME # else -# error Unknown platform +# error "No high resolution steady clock in your system, please provide a patch" # endif #endif @@ -37,6 +69,7 @@ namespace ipcdetail{ typedef unsigned long OS_process_id_t; typedef unsigned long OS_thread_id_t; +typedef void* OS_thread_t; typedef OS_thread_id_t OS_systemwide_thread_id_t; //process @@ -56,6 +89,78 @@ inline OS_thread_id_t get_invalid_thread_id() inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2) { return id1 == id2; } +//return the system tick in ns +inline unsigned long get_system_tick_ns() +{ + unsigned long curres; + winapi::set_timer_resolution(10000, 0, &curres); + //Windows API returns the value in hundreds of ns + return (curres - 1ul)*100ul; +} + +//return the system tick in us +inline unsigned long get_system_tick_us() +{ + unsigned long curres; + winapi::set_timer_resolution(10000, 0, &curres); + //Windows API returns the value in hundreds of ns + return (curres - 1ul)/10ul + 1ul; +} + +typedef unsigned __int64 OS_highres_count_t; + +inline unsigned long get_system_tick_in_highres_counts() +{ + __int64 freq; + unsigned long curres; + winapi::set_timer_resolution(10000, 0, &curres); + //Frequency in counts per second + if(!winapi::query_performance_frequency(&freq)){ + //Tick resolution in ms + return (curres-1ul)/10000ul + 1ul; + } + else{ + //In femtoseconds + __int64 count_fs = (1000000000000000LL - 1LL)/freq + 1LL; + __int64 tick_counts = (static_cast<__int64>(curres)*100000000LL - 1LL)/count_fs + 1LL; + return static_cast(tick_counts); + } +} + +inline OS_highres_count_t get_current_system_highres_count() +{ + __int64 count; + if(!winapi::query_performance_counter(&count)){ + count = winapi::get_tick_count(); + } + return count; +} + +inline void zero_highres_count(OS_highres_count_t &count) +{ count = 0; } + +inline bool is_highres_count_zero(const OS_highres_count_t &count) +{ return count == 0; } + +template +inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count) +{ + ostream << count; + return ostream; +} + +inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ return l - r; } + +inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ return l < r; } + +inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r) +{ return l < static_cast(r); } + +inline void thread_sleep_tick() +{ winapi::sleep_tick(); } + inline void thread_yield() { winapi::sched_yield(); } @@ -97,9 +202,17 @@ inline long double get_current_process_creation_time() CreationTime.dwLowDateTime*resolution; } +inline unsigned int get_num_cores() +{ + winapi::system_info sysinfo; + winapi::get_system_info( &sysinfo ); + //in Windows dw is long which is equal in bits to int + return static_cast(sysinfo.dwNumberOfProcessors); +} #else //#if (defined BOOST_INTERPROCESS_WINDOWS) +typedef pthread_t OS_thread_t; typedef pthread_t OS_thread_id_t; typedef pid_t OS_process_id_t; @@ -164,9 +277,135 @@ inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2) inline void thread_yield() { ::sched_yield(); } +#ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME +typedef struct timespec OS_highres_count_t; +#else +typedef unsigned long long OS_highres_count_t; +#endif + +inline unsigned long get_system_tick_ns() +{ + #ifdef _SC_CLK_TCK + long hz =::sysconf(_SC_CLK_TCK); // ticks per sec + if(hz <= 0){ //Try a typical value on error + hz = 100; + } + return 999999999ul/static_cast(hz)+1ul; + #else + #error "Can't obtain system tick value for your system, please provide a patch" + #endif +} + +inline unsigned long get_system_tick_in_highres_counts() +{ + #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME + return get_system_tick_ns(); + #else + mach_timebase_info_data_t info; + mach_timebase_info(&info); + //ns + return static_cast + ( + static_cast(get_system_tick_ns()) + / (static_cast(info.numer) / info.denom) + ); + #endif +} + +//return system ticks in us +inline unsigned long get_system_tick_us() +{ + return (get_system_tick_ns()-1)/1000ul + 1ul; +} + +inline OS_highres_count_t get_current_system_highres_count() +{ + #if defined(BOOST_INTERPROCESS_CLOCK_MONOTONIC) + struct timespec count; + ::clock_gettime(BOOST_INTERPROCESS_CLOCK_MONOTONIC, &count); + return count; + #elif defined(BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME) + return ::mach_absolute_time(); + #endif +} + +#ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME + +inline void zero_highres_count(OS_highres_count_t &count) +{ count.tv_sec = 0; count.tv_nsec = 0; } + +inline bool is_highres_count_zero(const OS_highres_count_t &count) +{ return count.tv_sec == 0 && count.tv_nsec == 0; } + +template +inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count) +{ + ostream << count.tv_sec << "s:" << count.tv_nsec << "ns"; + return ostream; +} + +inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ + OS_highres_count_t res; + + if (l.tv_nsec < r.tv_nsec){ + res.tv_nsec = 1000000000 + l.tv_nsec - r.tv_nsec; + res.tv_sec = l.tv_sec - 1 - r.tv_sec; + } + else{ + res.tv_nsec = l.tv_nsec - r.tv_nsec; + res.tv_sec = l.tv_sec - r.tv_sec; + } + + return res; +} + +inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ return l.tv_sec < r.tv_sec || (l.tv_sec == r.tv_sec && l.tv_nsec < r.tv_nsec); } + +inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r) +{ return !l.tv_sec && (static_cast(l.tv_nsec) < r); } + +#else + +inline void zero_highres_count(OS_highres_count_t &count) +{ count = 0; } + +inline bool is_highres_count_zero(const OS_highres_count_t &count) +{ return count == 0; } + +template +inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count) +{ + ostream << count ; + return ostream; +} + +inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ return l - r; } + +inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r) +{ return l < r; } + +inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r) +{ return l < static_cast(r); } + +#endif + +inline void thread_sleep_tick() +{ + struct timespec rqt; + //Sleep for the half of the tick time + rqt.tv_sec = 0; + rqt.tv_nsec = get_system_tick_ns()/2; + ::nanosleep(&rqt, 0); +} + inline void thread_sleep(unsigned int ms) { - const struct timespec rqt = { ms/1000u, (ms%1000u)*1000000u }; + struct timespec rqt; + rqt.tv_sec = ms/1000u; + rqt.tv_nsec = (ms%1000u)*1000000u; ::nanosleep(&rqt, 0); } @@ -189,6 +428,45 @@ inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id() inline long double get_current_process_creation_time() { return 0.0L; } +inline unsigned int get_num_cores() +{ + #ifdef _SC_NPROCESSORS_ONLN + long cores = ::sysconf(_SC_NPROCESSORS_ONLN); + // sysconf returns -1 if the name is invalid, the option does not exist or + // does not have a definite limit. + // if sysconf returns some other negative number, we have no idea + // what is going on. Default to something safe. + if(cores <= 0){ + return 1; + } + //Check for overflow (unlikely) + else if(static_cast(cores) >= + static_cast(static_cast(-1))){ + return static_cast(-1); + } + else{ + return static_cast(cores); + } + #elif defined(BOOST_INTERPROCESS_BSD_DERIVATIVE) && defined(HW_NCPU) + int request[2] = { CTL_HW, HW_NCPU }; + int num_cores; + std::size_t result_len = sizeof(num_cores); + if ( (::sysctl (request, 2, &num_cores, &result_len, 0, 0) < 0) || (num_cores <= 0) ){ + //Return a safe value + return 1; + } + else{ + return static_cast(num_cores); + } + #endif +} + +inline int thread_create(OS_thread_t * thread, void *(*start_routine)(void*), void* arg) +{ return pthread_create(thread, 0, start_routine, arg); } + +inline void thread_join(OS_thread_t thread) +{ (void)pthread_join(thread, 0); } + #endif //#if (defined BOOST_INTERPROCESS_WINDOWS) typedef char pid_str_t[sizeof(OS_process_id_t)*3+1]; @@ -202,6 +480,87 @@ inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid) inline void get_pid_str(pid_str_t &pid_str) { get_pid_str(pid_str, get_current_process_id()); } +#if defined(BOOST_INTERPROCESS_WINDOWS) + +inline int thread_create( OS_thread_t * thread, unsigned (__stdcall * start_routine) (void*), void* arg ) +{ + void* h = (void*)_beginthreadex( 0, 0, start_routine, arg, 0, 0 ); + + if( h != 0 ){ + *thread = h; + return 0; + } + else{ + return 1; + } +} + +inline void thread_join( OS_thread_t thread) +{ + winapi::wait_for_single_object( thread, winapi::infinite_time ); + winapi::close_handle( thread ); +} + +#endif + +class abstract_thread +{ + public: + virtual ~abstract_thread() {} + virtual void run() = 0; +}; + +#if defined(BOOST_INTERPROCESS_WINDOWS) + +inline unsigned __stdcall launch_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + pt->run(); + return 0; +} + +#else + +extern "C" void * launch_thread_routine( void * pv ); + +inline void * launch_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + pt->run(); + return 0; +} + +#endif + +template +class launch_thread_impl + : public abstract_thread +{ + public: + explicit launch_thread_impl( F f ) + : f_( f ) + {} + + void run() + { f_(); } + + private: + F f_; +}; + +template +inline int thread_launch( OS_thread_t & pt, F f ) +{ + std::auto_ptr p( new launch_thread_impl( f ) ); + + int r = thread_create(&pt, launch_thread_routine, p.get()); + if( r == 0 ){ + p.release(); + } + + return r; +} + } //namespace ipcdetail{ } //namespace interprocess { } //namespace boost { diff --git a/cpp/BoostParts/boost/interprocess/detail/tmp_dir_helpers.hpp b/cpp/BoostParts/boost/interprocess/detail/tmp_dir_helpers.hpp index e4e867e3..2af1a8a7 100644 --- a/cpp/BoostParts/boost/interprocess/detail/tmp_dir_helpers.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/tmp_dir_helpers.hpp @@ -58,7 +58,7 @@ namespace ipcdetail { struct ::timeval result; std::size_t result_len = sizeof result; - if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0) + if (::sysctl (request, 2, &result, &result_len, 0, 0) < 0) return; char bootstamp_str[256]; diff --git a/cpp/BoostParts/boost/interprocess/detail/win32_api.hpp b/cpp/BoostParts/boost/interprocess/detail/win32_api.hpp index 4bffb51c..67b5c13e 100644 --- a/cpp/BoostParts/boost/interprocess/detail/win32_api.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/win32_api.hpp @@ -883,6 +883,7 @@ extern "C" __declspec(dllimport) int __stdcall GetProcessTimes , interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime , interprocess_filetime *lpUserTime ); extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long); +extern "C" __declspec(dllimport) unsigned long __stdcall GetTickCount(void); extern "C" __declspec(dllimport) int __stdcall SwitchToThread(); extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError(); extern "C" __declspec(dllimport) void __stdcall SetLastError(unsigned long); @@ -943,7 +944,6 @@ extern "C" __declspec(dllimport) int __stdcall FreeLibrary(void *); extern "C" __declspec(dllimport) void *__stdcall GetProcAddress(void *, const char*); extern "C" __declspec(dllimport) void *__stdcall GetModuleHandleA(const char*); extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*); -extern "C" __declspec(dllimport) int __stdcall QueryPerformanceCounter(__int64 *lpPerformanceCount); //Advapi32.dll extern "C" __declspec(dllimport) long __stdcall RegOpenKeyExA(void *, const char *, unsigned long, unsigned long, void **); @@ -1013,6 +1013,12 @@ typedef long (__stdcall *NtQuerySection_t)(void*, section_information_class, int typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int); typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long); typedef long (__stdcall *NtClose_t) (void*); +typedef long (__stdcall *NtQueryTimerResolution_t) (unsigned long* LowestResolution, unsigned long* HighestResolution, unsigned long* CurrentResolution); +typedef long (__stdcall *NtSetTimerResolution_t) (unsigned long RequestedResolution, int Set, unsigned long* ActualResolution); + +//kernel32.dll +typedef int (__stdcall *QueryPerformanceCounter_t) (__int64 *lpPerformanceCount); +typedef int (__stdcall *QueryPerformanceFrequency_t)(__int64 *lpFrequency); } //namespace winapi { } //namespace interprocess { @@ -1047,10 +1053,13 @@ inline unsigned long make_lang_id(unsigned long p, unsigned long s) inline void sched_yield() { if(!SwitchToThread()){ - Sleep(1); + Sleep(0); } } +inline void sleep_tick() +{ Sleep(1); } + inline void sleep(unsigned long ms) { Sleep(ms); } @@ -1270,11 +1279,6 @@ inline long reg_query_value_ex(void *hKey, const char *lpValueName, unsigned lon inline long reg_close_key(void *hKey) { return RegCloseKey(hKey); } -inline bool query_performance_counter(__int64 *lpPerformanceCount) -{ - return 0 != QueryPerformanceCounter(lpPerformanceCount); -} - inline void initialize_object_attributes ( object_attributes_t *pobject_attr, unicode_string_t *name , unsigned long attr, void *rootdir, void *security_descr) @@ -1299,8 +1303,20 @@ inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, template struct function_address_holder { - enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NtQuerySection, NtOpenFile, NtClose, NumFunction }; - enum { NtDll_dll, NumModule }; + enum { NtSetInformationFile + , NtQuerySystemInformation + , NtQueryObject + , NtQuerySemaphore + , NtQuerySection + , NtOpenFile + , NtClose + , NtQueryTimerResolution + , NtSetTimerResolution + , QueryPerformanceCounter + , QueryPerformanceFrequency + , NumFunction + }; + enum { NtDll_dll, Kernel32_dll, NumModule }; private: static const char *FunctionNames[NumFunction]; @@ -1314,21 +1330,26 @@ struct function_address_holder static void *get_module_from_id(unsigned int id) { BOOST_ASSERT(id < (unsigned int)NumModule); - return get_module_handle(ModuleNames[id]); + void *addr = get_module_handle(ModuleNames[id]); + BOOST_ASSERT(addr); + return addr; } static void *get_module(const unsigned int id) { BOOST_ASSERT(id < (unsigned int)NumModule); - while(ModuleStates[id] < 2){ + for(unsigned i = 0; ModuleStates[id] < 2; ++i){ if(interlocked_compare_exchange(&ModuleStates[id], 1, 0) == 0){ ModuleAddresses[id] = get_module_from_id(id); interlocked_increment(&ModuleStates[id]); break; } - else{ + else if(i & 1){ sched_yield(); } + else{ + sleep_tick(); + } } return ModuleAddresses[id]; } @@ -1336,22 +1357,27 @@ struct function_address_holder static void *get_address_from_dll(const unsigned int id) { BOOST_ASSERT(id < (unsigned int)NumFunction); - return get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]); + void *addr = get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]); + BOOST_ASSERT(addr); + return addr; } public: static void *get(const unsigned int id) { BOOST_ASSERT(id < (unsigned int)NumFunction); - while(FunctionStates[id] < 2){ + for(unsigned i = 0; FunctionStates[id] < 2; ++i){ if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){ FunctionAddresses[id] = get_address_from_dll(id); interlocked_increment(&FunctionStates[id]); break; } - else{ + else if(i & 1){ sched_yield(); } + else{ + sleep_tick(); + } } return FunctionAddresses[id]; } @@ -1366,7 +1392,11 @@ const char *function_address_holder::FunctionNames[function_address_holde "NtQuerySemaphore", "NtQuerySection", "NtOpenFile", - "NtClose" + "NtClose", + "NtQueryTimerResolution", + "NtSetTimerResolution", + "QueryPerformanceCounter", + "QueryPerformanceFrequency" }; template @@ -1378,13 +1408,18 @@ unsigned int function_address_holder::FunctionModules[function_address_ho NtDll_dll, NtDll_dll, NtDll_dll, - NtDll_dll + NtDll_dll, + NtDll_dll, + NtDll_dll, + Kernel32_dll, + Kernel32_dll }; template const char *function_address_holder::ModuleNames[function_address_holder::NumModule] = { - "ntdll.dll" + "ntdll.dll", + "kernel32.dll" }; @@ -1549,7 +1584,7 @@ class nt_query_mem_deleter delete[]m_buf; } - void realloc(std::size_t num_bytes) + void realloc_mem(std::size_t num_bytes) { num_bytes += rename_suffix + rename_offset; char *buf = m_buf; @@ -1584,7 +1619,7 @@ class c_heap_deleter if(m_buf) ::free(m_buf); } - void realloc(std::size_t num_bytes) + void realloc_mem(std::size_t num_bytes) { void *buf = ::realloc(m_buf, num_bytes); if(!buf){ @@ -1639,7 +1674,7 @@ inline bool unlink_file(const char *filename) //Obtain file name with guessed length if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){ //Obtain file name with exact length buffer - nt_query_mem.realloc(size); + nt_query_mem.realloc_mem(size); if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){ return false; } @@ -2021,7 +2056,7 @@ inline bool get_last_bootup_time(std::string &stamp) if (error_insufficient_buffer == status) { status = 0; dwBytesToRead = dwMinimumBytesToRead; - heap_deleter.realloc(dwMinimumBytesToRead); + heap_deleter.realloc_mem(dwMinimumBytesToRead); if (!heap_deleter.get()){ return false; } @@ -2065,11 +2100,8 @@ inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size) interprocess_section_basic_information info; unsigned long ntstatus = pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0); - if(ntstatus){ - return false; - } size = info.section_size; - return true; + return !ntstatus; } inline bool get_semaphore_info(void *handle, long &count, long &limit) @@ -2079,14 +2111,41 @@ inline bool get_semaphore_info(void *handle, long &count, long &limit) (winapi::NtQuerySemaphore_t)dll_func::get(winapi::dll_func::NtQuerySemaphore); unsigned int ret_len; long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len); - if(status){ - return false; - } count = info.count; limit = info.limit; - return true; + return !status; } +inline bool query_timer_resolution(unsigned long *lowres, unsigned long *highres, unsigned long *curres) +{ + winapi::NtQueryTimerResolution_t pNtQueryTimerResolution = + (winapi::NtQueryTimerResolution_t)dll_func::get(winapi::dll_func::NtQueryTimerResolution); + return !pNtQueryTimerResolution(lowres, highres, curres); +} + +inline bool set_timer_resolution(unsigned long RequestedResolution, int Set, unsigned long* ActualResolution) +{ + winapi::NtSetTimerResolution_t pNtSetTimerResolution = + (winapi::NtSetTimerResolution_t)dll_func::get(winapi::dll_func::NtSetTimerResolution); + return !pNtSetTimerResolution(RequestedResolution, Set, ActualResolution); +} + +inline bool query_performance_counter(__int64 *lpPerformanceCount) +{ + QueryPerformanceCounter_t pQueryPerformanceCounter = (QueryPerformanceCounter_t) + dll_func::get(dll_func::QueryPerformanceCounter); + return 0 != pQueryPerformanceCounter(lpPerformanceCount); +} + +inline bool query_performance_frequency(__int64 *lpFrequency) +{ + QueryPerformanceCounter_t pQueryPerformanceFrequency = (QueryPerformanceFrequency_t) + dll_func::get(dll_func::QueryPerformanceFrequency); + return 0 != pQueryPerformanceFrequency(lpFrequency); +} + +inline unsigned long get_tick_count() +{ return GetTickCount(); } } //namespace winapi } //namespace interprocess diff --git a/cpp/BoostParts/boost/interprocess/detail/windows_intermodule_singleton.hpp b/cpp/BoostParts/boost/interprocess/detail/windows_intermodule_singleton.hpp index 194e566a..946f6a7b 100644 --- a/cpp/BoostParts/boost/interprocess/detail/windows_intermodule_singleton.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/windows_intermodule_singleton.hpp @@ -135,6 +135,7 @@ class windows_semaphore_based_map success = success && m_sem_map.open_or_create (name.c_str(), initial_count, max_count, perm, created); if(!success){ + delete m; //winapi_xxx wrappers do the cleanup... throw int(0); } @@ -217,7 +218,9 @@ class windows_semaphore_based_map scoped_lock lck(m_mtx_lock); m_sem_count.wait(); if(0 == m_sem_count.value()){ - delete &this->get_map_unlocked(); + map_type &map = this->get_map_unlocked(); + BOOST_ASSERT(map.empty()); + delete ↦ } //First close sems to protect this with the external mutex m_sem_map.close(); diff --git a/cpp/BoostParts/boost/interprocess/detail/workaround.hpp b/cpp/BoostParts/boost/interprocess/detail/workaround.hpp index 2ffe8128..6ce2ea1c 100644 --- a/cpp/BoostParts/boost/interprocess/detail/workaround.hpp +++ b/cpp/BoostParts/boost/interprocess/detail/workaround.hpp @@ -24,8 +24,25 @@ #if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0) //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it. - //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seem to work. - #if !defined(__CYGWIN__) && !defined(__APPLE__) + #if defined(__CYGWIN__) + #define BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED + //Mac Os X < Lion (10.7) might define _POSIX_THREAD_PROCESS_SHARED but there is no real support. + #elif defined(__APPLE__) + #include "TargetConditionals.h" + //Check we're on Mac OS target + #if defined(TARGET_OS_MAC) + #include "AvailabilityMacros.h" + //If minimum target for this compilation is older than Mac Os Lion, then we are out of luck + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 + #define BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED + #endif + #endif + #endif + + //If buggy _POSIX_THREAD_PROCESS_SHARED is detected avoid using it + #if defined(BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED) + #undef BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED + #else #define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED #endif #endif diff --git a/cpp/BoostParts/boost/interprocess/errors.hpp b/cpp/BoostParts/boost/interprocess/errors.hpp index 345ca311..3a3bb533 100644 --- a/cpp/BoostParts/boost/interprocess/errors.hpp +++ b/cpp/BoostParts/boost/interprocess/errors.hpp @@ -114,7 +114,7 @@ enum error_code_t not_such_file_or_directory, invalid_argument, timeout_when_locking_error, - timeout_when_waiting_error, + timeout_when_waiting_error }; typedef int native_error_t; diff --git a/cpp/BoostParts/boost/interprocess/segment_manager.hpp b/cpp/BoostParts/boost/interprocess/segment_manager.hpp index a0f948f6..9113acba 100644 --- a/cpp/BoostParts/boost/interprocess/segment_manager.hpp +++ b/cpp/BoostParts/boost/interprocess/segment_manager.hpp @@ -847,7 +847,6 @@ class segment_manager { (void)is_intrusive; typedef IndexType > index_type; - typedef ipcdetail::index_key index_key_t; typedef typename index_type::iterator index_it; //------------------------------- @@ -949,7 +948,6 @@ class segment_manager { (void)is_intrusive_index; typedef IndexType > index_type; - typedef ipcdetail::index_key index_key_t; typedef typename index_type::iterator index_it; typedef typename index_type::value_type intrusive_value_type; diff --git a/cpp/BoostParts/boost/interprocess/streams/bufferstream.hpp b/cpp/BoostParts/boost/interprocess/streams/bufferstream.hpp index 9a2681ab..404880d2 100644 --- a/cpp/BoostParts/boost/interprocess/streams/bufferstream.hpp +++ b/cpp/BoostParts/boost/interprocess/streams/bufferstream.hpp @@ -251,8 +251,11 @@ class basic_bufferbuf //!A basic_istream class that uses a fixed size character buffer //!as its formatting buffer. template -class basic_ibufferstream - : public std::basic_istream +class basic_ibufferstream : + /// @cond + private basic_bufferbuf, + /// @endcond + public std::basic_istream { public: // Typedefs typedef typename std::basic_ios @@ -262,24 +265,40 @@ class basic_ibufferstream typedef typename std::basic_ios::off_type off_type; typedef typename std::basic_ios::traits_type traits_type; + /// @cond private: - typedef std::basic_ios basic_ios_t; - typedef std::basic_istream base_t; + typedef basic_bufferbuf bufferbuf_t; + typedef std::basic_ios basic_ios_t; + typedef std::basic_istream base_t; + bufferbuf_t & get_buf() { return *this; } + const bufferbuf_t & get_buf() const{ return *this; } + /// @endcond public: //!Constructor. //!Does not throw. basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in) - : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(mode | std::ios_base::in) + , base_t(&get_buf()) + {} //!Constructor. Assigns formatting buffer. //!Does not throw. basic_ibufferstream(const CharT *buf, std::size_t length, std::ios_base::openmode mode = std::ios_base::in) - : basic_ios_t(), base_t(0), - m_buf(const_cast(buf), length, mode | std::ios_base::in) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(const_cast(buf), length, mode | std::ios_base::in) + , base_t(&get_buf()) + {} ~basic_ibufferstream(){}; @@ -287,29 +306,27 @@ class basic_ibufferstream //!Returns the address of the stored //!stream buffer. basic_bufferbuf* rdbuf() const - { return const_cast*>(&m_buf); } + { return const_cast*>(&get_buf()); } //!Returns the pointer and size of the internal buffer. //!Does not throw. std::pair buffer() const - { return m_buf.buffer(); } + { return get_buf().buffer(); } //!Sets the underlying buffer to a new value. Resets //!stream position. Does not throw. void buffer(const CharT *buf, std::size_t length) - { m_buf.buffer(const_cast(buf), length); } - - /// @cond - private: - basic_bufferbuf m_buf; - /// @endcond + { get_buf().buffer(const_cast(buf), length); } }; //!A basic_ostream class that uses a fixed size character buffer //!as its formatting buffer. template -class basic_obufferstream - : public std::basic_ostream +class basic_obufferstream : + /// @cond + private basic_bufferbuf, + /// @endcond + public std::basic_ostream { public: typedef typename std::basic_ios @@ -321,23 +338,38 @@ class basic_obufferstream /// @cond private: + typedef basic_bufferbuf bufferbuf_t; typedef std::basic_ios basic_ios_t; typedef std::basic_ostream base_t; + bufferbuf_t & get_buf() { return *this; } + const bufferbuf_t & get_buf() const{ return *this; } /// @endcond + public: //!Constructor. //!Does not throw. basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(mode | std::ios_base::out) + , base_t(&get_buf()) + {} //!Constructor. Assigns formatting buffer. //!Does not throw. basic_obufferstream(CharT *buf, std::size_t length, std::ios_base::openmode mode = std::ios_base::out) - : basic_ios_t(), base_t(0), - m_buf(buf, length, mode | std::ios_base::out) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(buf, length, mode | std::ios_base::out) + , base_t(&get_buf()) + {} ~basic_obufferstream(){} @@ -345,31 +377,28 @@ class basic_obufferstream //!Returns the address of the stored //!stream buffer. basic_bufferbuf* rdbuf() const - { return const_cast*>(&m_buf); } + { return const_cast*>(&get_buf()); } //!Returns the pointer and size of the internal buffer. //!Does not throw. std::pair buffer() const - { return m_buf.buffer(); } + { return get_buf().buffer(); } //!Sets the underlying buffer to a new value. Resets //!stream position. Does not throw. void buffer(CharT *buf, std::size_t length) - { m_buf.buffer(buf, length); } - - /// @cond - private: - basic_bufferbuf m_buf; - /// @endcond + { get_buf().buffer(buf, length); } }; //!A basic_iostream class that uses a fixed size character buffer //!as its formatting buffer. template -class basic_bufferstream - : public std::basic_iostream - +class basic_bufferstream : + /// @cond + private basic_bufferbuf, + /// @endcond + public std::basic_iostream { public: // Typedefs typedef typename std::basic_ios @@ -381,8 +410,11 @@ class basic_bufferstream /// @cond private: - typedef std::basic_ios basic_ios_t; - typedef std::basic_iostream base_t; + typedef basic_bufferbuf bufferbuf_t; + typedef std::basic_ios basic_ios_t; + typedef std::basic_iostream base_t; + bufferbuf_t & get_buf() { return *this; } + const bufferbuf_t & get_buf() const{ return *this; } /// @endcond public: @@ -390,16 +422,28 @@ class basic_bufferstream //!Does not throw. basic_bufferstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(mode) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(mode) + , base_t(&get_buf()) + {} //!Constructor. Assigns formatting buffer. //!Does not throw. basic_bufferstream(CharT *buf, std::size_t length, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : basic_ios_t(), base_t(0), m_buf(buf, length, mode) - { basic_ios_t::init(&m_buf); } + : //basic_ios_t() is called first (lefting it uninitialized) as it's a + //virtual base of basic_istream. The class will be initialized when + //basic_istream is constructed calling basic_ios_t::init(). + //As bufferbuf_t's constructor does not throw there is no risk of + //calling the basic_ios_t's destructor without calling basic_ios_t::init() + bufferbuf_t(buf, length, mode) + , base_t(&get_buf()) + {} ~basic_bufferstream(){} @@ -407,22 +451,17 @@ class basic_bufferstream //!Returns the address of the stored //!stream buffer. basic_bufferbuf* rdbuf() const - { return const_cast*>(&m_buf); } + { return const_cast*>(&get_buf()); } //!Returns the pointer and size of the internal buffer. //!Does not throw. std::pair buffer() const - { return m_buf.buffer(); } + { return get_buf().buffer(); } //!Sets the underlying buffer to a new value. Resets //!stream position. Does not throw. void buffer(CharT *buf, std::size_t length) - { m_buf.buffer(buf, length); } - - /// @cond - private: - basic_bufferbuf m_buf; - /// @endcond + { get_buf().buffer(buf, length); } }; //Some typedefs to simplify usage diff --git a/cpp/BoostParts/boost/interprocess/sync/posix/mutex.hpp b/cpp/BoostParts/boost/interprocess/sync/posix/mutex.hpp index 344c5e90..6bc45ca4 100644 --- a/cpp/BoostParts/boost/interprocess/sync/posix/mutex.hpp +++ b/cpp/BoostParts/boost/interprocess/sync/posix/mutex.hpp @@ -44,6 +44,7 @@ #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS # include +# include #endif #include @@ -119,6 +120,7 @@ inline bool posix_mutex::timed_lock(const boost::posix_time::ptime &abs_time) //Obtain current count and target time boost::posix_time::ptime now = microsec_clock::universal_time(); + spin_wait swait; do{ if(this->try_lock()){ break; @@ -129,7 +131,7 @@ inline bool posix_mutex::timed_lock(const boost::posix_time::ptime &abs_time) return false; } // relinquish current time slice - thread_yield(); + swait.yield(); }while (true); return true; diff --git a/cpp/BoostParts/boost/interprocess/sync/posix/recursive_mutex.hpp b/cpp/BoostParts/boost/interprocess/sync/posix/recursive_mutex.hpp index 385d714f..ce2ad689 100644 --- a/cpp/BoostParts/boost/interprocess/sync/posix/recursive_mutex.hpp +++ b/cpp/BoostParts/boost/interprocess/sync/posix/recursive_mutex.hpp @@ -38,6 +38,7 @@ #include #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS # include +# include #endif #include @@ -108,7 +109,7 @@ inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &ab //Obtain current count and target time boost::posix_time::ptime now = microsec_clock::universal_time(); - + spin_wait swait; do{ if(this->try_lock()){ break; @@ -119,7 +120,7 @@ inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &ab return false; } // relinquish current time slice - thread_yield(); + swait.yield(); }while (true); return true; diff --git a/cpp/BoostParts/boost/interprocess/sync/spin/mutex.hpp b/cpp/BoostParts/boost/interprocess/sync/spin/mutex.hpp index 94c26a16..7a77549e 100644 --- a/cpp/BoostParts/boost/interprocess/sync/spin/mutex.hpp +++ b/cpp/BoostParts/boost/interprocess/sync/spin/mutex.hpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace boost { namespace interprocess { @@ -60,6 +61,7 @@ inline spin_mutex::~spin_mutex() inline void spin_mutex::lock(void) { + spin_wait swait; do{ boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast(&m_s), 1, 0); @@ -67,7 +69,7 @@ inline void spin_mutex::lock(void) break; } // relinquish current timeslice - ipcdetail::thread_yield(); + swait.yield(); }while (true); } @@ -86,6 +88,7 @@ inline bool spin_mutex::timed_lock(const boost::posix_time::ptime &abs_time) //Obtain current count and target time boost::posix_time::ptime now = microsec_clock::universal_time(); + spin_wait swait; do{ if(this->try_lock()){ break; @@ -96,7 +99,7 @@ inline bool spin_mutex::timed_lock(const boost::posix_time::ptime &abs_time) return false; } // relinquish current time slice - ipcdetail::thread_yield(); + swait.yield(); }while (true); return true; diff --git a/cpp/BoostParts/boost/interprocess/sync/spin/wait.hpp b/cpp/BoostParts/boost/interprocess/sync/spin/wait.hpp new file mode 100644 index 00000000..0707bd8d --- /dev/null +++ b/cpp/BoostParts/boost/interprocess/sync/spin/wait.hpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Peter Dimov 2008. +// (C) Copyright Ion Gaztanaga 2013-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) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//Parts of this file come from boost/smart_ptr/detail/yield_k.hpp +//Many thanks to Peter Dimov. + +#ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED +#define BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +//#define BOOST_INTERPROCESS_SPIN_WAIT_DEBUG +#ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG +#include +#endif + +// BOOST_INTERPROCESS_SMT_PAUSE + +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) + +extern "C" void _mm_pause(); +#pragma intrinsic( _mm_pause ) + +#define BOOST_INTERPROCESS_SMT_PAUSE _mm_pause(); + +#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) + +#define BOOST_INTERPROCESS_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); + +#endif + +namespace boost{ +namespace interprocess{ +namespace ipcdetail { + +template +class num_core_holder +{ + public: + static unsigned int get() + { + if(!num_cores){ + return ipcdetail::get_num_cores(); + } + else{ + return num_cores; + } + } + + private: + static unsigned int num_cores; +}; + +template +unsigned int num_core_holder::num_cores = ipcdetail::get_num_cores(); + +} //namespace ipcdetail { + +class spin_wait +{ + public: + + static const unsigned int nop_pause_limit = 32u; + spin_wait() + : m_count_start(), m_ul_yield_only_counts(), m_k() + {} + + #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG + ~spin_wait() + { + if(m_k){ + std::cout << "final m_k: " << m_k + << " system tick(us): " << ipcdetail::get_system_tick_us() << std::endl; + } + } + #endif + + unsigned int count() const + { return m_k; } + + void yield() + { + //Lazy initialization of limits + if( !m_k){ + this->init_limits(); + } + //Nop tries + if( m_k < (nop_pause_limit >> 2) ){ + + } + //Pause tries if the processor supports it + #if defined(BOOST_INTERPROCESS_SMT_PAUSE) + else if( m_k < nop_pause_limit ){ + BOOST_INTERPROCESS_SMT_PAUSE + } + #endif + //Yield/Sleep strategy + else{ + //Lazy initialization of tick information + if(m_k == nop_pause_limit){ + this->init_tick_info(); + } + else if( this->yield_or_sleep() ){ + ipcdetail::thread_yield(); + } + else{ + ipcdetail::thread_sleep_tick(); + } + } + ++m_k; + } + + void reset() + { + m_k = 0u; + } + + private: + + void init_limits() + { + unsigned int num_cores = ipcdetail::num_core_holder<0>::get(); + m_k = num_cores > 1u ? 0u : nop_pause_limit; + } + + void init_tick_info() + { + m_ul_yield_only_counts = ipcdetail::get_system_tick_in_highres_counts(); + m_count_start = ipcdetail::get_current_system_highres_count(); + } + + //Returns true if yield must be called, false is sleep must be called + bool yield_or_sleep() + { + if(!m_ul_yield_only_counts){ //If yield-only limit was reached then yield one in every two tries + return (m_k & 1u) != 0; + } + else{ //Try to see if we've reched yield-only time limit + const ipcdetail::OS_highres_count_t now = ipcdetail::get_current_system_highres_count(); + const ipcdetail::OS_highres_count_t elapsed = ipcdetail::system_highres_count_subtract(now, m_count_start); + if(!ipcdetail::system_highres_count_less_ul(elapsed, m_ul_yield_only_counts)){ + #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG + std::cout << "elapsed!\n" + << " m_ul_yield_only_counts: " << m_ul_yield_only_counts + << " system tick(us): " << ipcdetail::get_system_tick_us() << '\n' + << " m_k: " << m_k << " elapsed counts: "; + ipcdetail::ostream_highres_count(std::cout, elapsed) << std::endl; + #endif + //Yield-only time reached, now it's time to sleep + m_ul_yield_only_counts = 0ul; + return false; + } + } + return true; //Otherwise yield + } + + ipcdetail::OS_highres_count_t m_count_start; + unsigned long m_ul_yield_only_counts; + unsigned int m_k; +}; + +} // namespace interprocess +} // namespace boost + +#include + +#endif // #ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED diff --git a/cpp/BoostParts/boost/intrusive/bstree.hpp b/cpp/BoostParts/boost/intrusive/bstree.hpp new file mode 100644 index 00000000..32554fb5 --- /dev/null +++ b/cpp/BoostParts/boost/intrusive/bstree.hpp @@ -0,0 +1,2014 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_BSTREE_HPP +#define BOOST_INTRUSIVE_BSTREE_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +struct bstree_defaults +{ + typedef detail::default_bstree_hook proto_value_traits; + static const bool constant_time_size = true; + typedef std::size_t size_type; + typedef void compare; + static const bool floating_point = true; //For sgtree + typedef void priority; //For treap +}; + +template +struct bstbase3 + : public detail::get_real_value_traits::type::node_traits::node + , public ValueTraits +{ + typedef ValueTraits value_traits; + typedef typename detail::get_real_value_traits::type real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node_type; + typedef typename get_algo::type node_algorithms; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + + bstbase3(const ValueTraits &vtraits) + : ValueTraits(vtraits) + {} + + static const bool external_value_traits = + detail::external_value_traits_bool_is_true::value; + + node_ptr header_ptr() + { return pointer_traits::pointer_to(static_cast(*this)); } + + const_node_ptr header_ptr() const + { return pointer_traits::pointer_to(static_cast(*this)); } + + const value_traits &val_traits() const + { return *this; } + + value_traits &val_traits() + { return *this; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return *this; } + + const real_value_traits &get_real_value_traits(detail::bool_) const + { return this->val_traits().get_value_traits(*this); } + + real_value_traits &get_real_value_traits(detail::bool_) + { return *this; } + + real_value_traits &get_real_value_traits(detail::bool_) + { return this->val_traits().get_value_traits(*this); } + + const real_value_traits &get_real_value_traits() const + { return this->get_real_value_traits(detail::bool_()); } + + real_value_traits &get_real_value_traits() + { return this->get_real_value_traits(detail::bool_()); } + + typedef typename pointer_traits::template rebind_pointer::type const_real_value_traits_ptr; + + const_real_value_traits_ptr real_value_traits_ptr() const + { return pointer_traits::pointer_to(this->get_real_value_traits()); } + + + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef boost::intrusive::detail::reverse_iterator reverse_iterator; + typedef boost::intrusive::detail::reverse_iterator const_reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + + iterator begin() + { return iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); } + + const_iterator begin() const + { return cbegin(); } + + const_iterator cbegin() const + { return const_iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); } + + iterator end() + { return iterator (this->header_ptr(), this->real_value_traits_ptr()); } + + const_iterator end() const + { return cend(); } + + const_iterator cend() const + { return const_iterator (detail::uncast(this->header_ptr()), this->real_value_traits_ptr()); } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + const_reverse_iterator crbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + const_reverse_iterator crend() const + { return const_reverse_iterator(begin()); } + + void replace_node(iterator replace_this, reference with_this) + { + node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) + , this->header_ptr() + , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); + } + + void rebalance() + { node_algorithms::rebalance(this->header_ptr()); } + + iterator rebalance_subtree(iterator root) + { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->real_value_traits_ptr()); } + + static iterator s_iterator_to(reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr()); + } + + static const_iterator s_iterator_to(const_reference value) + { + BOOST_STATIC_ASSERT((!stateful_value_traits)); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), const_real_value_traits_ptr()); + } + + iterator iterator_to(reference value) + { return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); } + + const_iterator iterator_to(const_reference value) const + { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this->real_value_traits_ptr()); } + + static void init_node(reference value) + { node_algorithms::init(value_traits::to_node_ptr(value)); } + +}; + +template +struct bstbase2 + : public bstbase3 + , public detail::ebo_functor_holder::type::value_type + >::type> +{ + typedef bstbase3 treeheader_t; + typedef typename treeheader_t::real_value_traits real_value_traits; + typedef typename treeheader_t::node_algorithms node_algorithms; + typedef typename get_less + < VoidOrKeyComp, typename real_value_traits::value_type>::type value_compare; + typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare; + typedef typename treeheader_t::iterator iterator; + typedef typename treeheader_t::const_iterator const_iterator; + typedef typename treeheader_t::node_ptr node_ptr; + typedef typename treeheader_t::const_node_ptr const_node_ptr; + + bstbase2(const value_compare &comp, const ValueTraits &vtraits) + : treeheader_t(vtraits), detail::ebo_functor_holder(comp) + {} + + const value_compare &comp() const + { return this->get(); } + + value_compare &comp() + { return this->get(); } + + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + value_compare value_comp() const + { return this->comp(); } + + key_compare key_comp() const + { return this->comp(); } + + iterator lower_bound(const_reference value) + { return this->lower_bound(value, this->comp()); } + + const_iterator lower_bound(const_reference value) const + { return this->lower_bound(value, this->comp()); } + + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return iterator(node_algorithms::lower_bound + (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + template + const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return const_iterator(node_algorithms::lower_bound + (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + iterator upper_bound(const_reference value) + { return this->upper_bound(value, this->comp()); } + + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return iterator(node_algorithms::upper_bound + (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + const_iterator upper_bound(const_reference value) const + { return this->upper_bound(value, this->comp()); } + + template + const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return const_iterator(node_algorithms::upper_bound + (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + iterator find(const_reference value) + { return this->find(value, this->comp()); } + + template + iterator find(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return iterator + (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + const_iterator find(const_reference value) const + { return this->find(value, this->comp()); } + + template + const_iterator find(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + return const_iterator + (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); + } + + std::pair equal_range(const_reference value) + { return this->equal_range(value, this->comp()); } + + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp)); + return std::pair( iterator(ret.first, this->real_value_traits_ptr()) + , iterator(ret.second, this->real_value_traits_ptr())); + } + + std::pair + equal_range(const_reference value) const + { return this->equal_range(value, this->comp()); } + + template + std::pair + equal_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp)); + return std::pair( const_iterator(ret.first, this->real_value_traits_ptr()) + , const_iterator(ret.second, this->real_value_traits_ptr())); + } + + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); } + + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair( iterator(ret.first, this->real_value_traits_ptr()) + , iterator(ret.second, this->real_value_traits_ptr())); + } + + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); } + + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::bounded_range + (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair( const_iterator(ret.first, this->real_value_traits_ptr()) + , const_iterator(ret.second, this->real_value_traits_ptr())); + } + + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + ocomp(key_value_comp, &this->get_real_value_traits()); + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), key, ocomp, commit_data)); + return std::pair(iterator(ret.first, this->real_value_traits_ptr()), ret.second); + } + + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) + { + detail::key_nodeptr_comp + ocomp(key_value_comp, &this->get_real_value_traits()); + std::pair ret = + (node_algorithms::insert_unique_check + (this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data)); + return std::pair(iterator(ret.first, this->real_value_traits_ptr()), ret.second); + } +}; + +template +struct bstbase + : public detail::size_holder + , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType> +{ + typedef typename detail::get_real_value_traits::type real_value_traits; + typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type; + typedef typename base_type::value_compare value_compare; + typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::reference reference; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::node_traits node_traits; + typedef typename get_algo + ::type algo_type; + typedef SizeType size_type; + + bstbase(const value_compare & comp, const ValueTraits &vtraits) + : base_type(comp, vtraits) + {} + + public: + typedef detail::size_holder size_traits; + + size_traits &sz_traits() + { return *this; } + + const size_traits &sz_traits() const + { return *this; } + + size_type count(const_reference value) const + { return size_type(this->count(value, this->comp())); } + + template + size_type count(const KeyType &key, KeyValueCompare comp) const + { + std::pair ret = this->equal_range(key, comp); + return size_type(std::distance(ret.first, ret.second)); + } + + bool empty() const + { + if(ConstantTimeSize){ + return !this->sz_traits().get_size(); + } + else{ + return algo_type::unique(this->header_ptr()); + } + } +}; + + +/// @endcond + +//! The class template bstree is an unbalanced intrusive binary search tree +//! container. The no-throw guarantee holds only, if the value_compare object +//! doesn't throw. +//! +//! The complexity guarantees only hold if the tree is balanced, logarithmic +//! complexity would increase to linear if the tree is totally unbalanced. +//! +//! The template parameter \c T is the type to be managed by the container. +//! The user can specify additional options and if no options are provided +//! default options are used. +//! +//! The container supports the following options: +//! \c base_hook<>/member_hook<>/value_traits<>, +//! \c constant_time_size<>, \c size_type<> and +//! \c compare<>. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +class bstree_impl + : public bstbase + , private detail::clear_on_destructor_base + < bstree_impl + , is_safe_autounlink::type::link_mode>::value + > +{ + template friend class detail::clear_on_destructor_base; + public: + typedef ValueTraits value_traits; + /// @cond + static const bool external_value_traits = + detail::external_value_traits_bool_is_true::value; + typedef typename detail::get_real_value_traits::type real_value_traits; + typedef bstbase data_type; + typedef tree_iterator iterator_type; + typedef tree_iterator const_iterator_type; + /// @endcond + + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::element_type) value_type; + typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::reference) const_reference; + typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits::difference_type) difference_type; + typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type; + typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare; + typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare; + typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator; + typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator) reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator) const_reverse_iterator; + typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::node_traits) node_traits; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr; + typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr; + /// @cond + typedef typename get_algo::type algo_type; + /// @endcond + typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms; + + static const bool constant_time_size = ConstantTimeSize; + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + /// @cond + private: + + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl) + + static const bool safemode_or_autounlink = is_safe_autounlink::value; + + //Constant-time size is incompatible with auto-unlink hooks! + BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); + + + protected: + + + /// @endcond + + public: + + typedef typename node_algorithms::insert_commit_data insert_commit_data; + + //! Effects: Constructs an empty container. + //! + //! Complexity: Constant. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructorof the value_compare object throws. Basic guarantee. + explicit bstree_impl( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_type(cmp, v_traits) + { + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(size_type(0)); + } + + //! Requires: Dereferencing iterator must yield an lvalue of type value_type. + //! cmp must be a comparison function that induces a strict weak ordering. + //! + //! Effects: Constructs an empty container and inserts elements from + //! [b, e). + //! + //! Complexity: Linear in N if [b, e) is already sorted using + //! comp and otherwise N * log N, where N is the distance between first and last. + //! + //! Throws: If value_traits::node_traits::node + //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) + //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee. + template + bstree_impl( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : data_type(cmp, v_traits) + { + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(size_type(0)); + if(unique) + this->insert_unique(b, e); + else + this->insert_equal(b, e); + } + + //! Effects: to-do + //! + bstree_impl(BOOST_RV_REF(bstree_impl) x) + : data_type(::boost::move(x.comp()), ::boost::move(x.val_traits())) + { + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x) + { this->swap(x); return *this; } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! Effects: Detaches all elements from this. The objects in the set + //! are not deleted (i.e. no destructors are called), but the nodes according to + //! the value_traits template parameter are reinitialized and thus can be reused. + //! + //! Complexity: Linear to elements contained in *this. + //! + //! Throws: Nothing. + ~bstree_impl() + {} + + //! Effects: Returns an iterator pointing to the beginning of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator begin(); + + //! Effects: Returns a const_iterator pointing to the beginning of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator begin() const; + + //! Effects: Returns a const_iterator pointing to the beginning of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cbegin() const; + + //! Effects: Returns an iterator pointing to the end of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator end(); + + //! Effects: Returns a const_iterator pointing to the end of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator end() const; + + //! Effects: Returns a const_iterator pointing to the end of the container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator cend() const; + + //! Effects: Returns a reverse_iterator pointing to the beginning of the + //! reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rbegin(); + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rbegin() const; + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crbegin() const; + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + reverse_iterator rend(); + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator rend() const; + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed container. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_reverse_iterator crend() const; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Precondition: end_iterator must be a valid end iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static bstree_impl &container_from_end_iterator(iterator end_iterator) + { + return *static_cast + (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); + } + + //! Precondition: end_iterator must be a valid end const_iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) + { + return *static_cast + (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); + } + + //! Precondition: it must be a valid iterator + //! of the container. + //! + //! Effects: Returns a const reference to the container associated to the iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic. + static bstree_impl &container_from_iterator(iterator it) + { return container_from_end_iterator(it.end_iterator_from_it()); } + + //! Precondition: it must be a valid end const_iterator + //! of container. + //! + //! Effects: Returns a const reference to the container associated to the end iterator + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic. + static const bstree_impl &container_from_iterator(const_iterator it) + { return container_from_end_iterator(it.end_iterator_from_it()); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Returns the key_compare object used by the container. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + key_compare key_comp() const; + + //! Effects: Returns the value_compare object used by the container. + //! + //! Complexity: Constant. + //! + //! Throws: If value_compare copy-constructor throws. + value_compare value_comp() const; + + //! Effects: Returns true if the container is empty. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + bool empty() const; + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Effects: Returns the number of elements stored in the container. + //! + //! Complexity: Linear to elements contained in *this + //! if constant-time size option is disabled. Constant time otherwise. + //! + //! Throws: Nothing. + size_type size() const + { + if(constant_time_size) + return this->sz_traits().get_size(); + else{ + return (size_type)node_algorithms::size(this->header_ptr()); + } + } + + //! Effects: Swaps the contents of two containers. + //! + //! Complexity: Constant. + //! + //! Throws: If the comparison functor's swap call throws. + void swap(bstree_impl& other) + { + //This can throw + using std::swap; + swap(this->comp(), this->comp()); + //These can't throw + node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr())); + if(constant_time_size){ + size_type backup = this->sz_traits().get_size(); + this->sz_traits().set_size(other.sz_traits().get_size()); + other.sz_traits().set_size(backup); + } + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! Cloner should yield to nodes equivalent to the original nodes. + //! + //! Effects: Erases all the elements from *this + //! calling Disposer::operator()(pointer), clones all the + //! elements from src calling Cloner::operator()(const_reference ) + //! and inserts them on *this. Copies the predicate from the source container. + //! + //! If cloner throws, all cloned elements are unlinked and disposed + //! calling Disposer::operator()(pointer). + //! + //! Complexity: Linear to erased plus inserted elements. + //! + //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. + template + void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + if(!src.empty()){ + detail::exception_disposer + rollback(*this, disposer); + node_algorithms::clone + (const_node_ptr(src.header_ptr()) + ,node_ptr(this->header_ptr()) + ,detail::node_cloner (cloner, &this->get_real_value_traits()) + ,detail::node_disposer(disposer, &this->get_real_value_traits())); + this->sz_traits().set_size(src.sz_traits().get_size()); + this->comp() = src.comp(); + rollback.release(); + } + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the container before the upper bound. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(reference value) + { + detail::key_nodeptr_comp + key_node_comp(this->comp(), &this->get_real_value_traits()); + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + iterator ret(node_algorithms::insert_equal_upper_bound + (this->header_ptr(), to_insert, key_node_comp), this->real_value_traits_ptr()); + this->sz_traits().increment(); + return ret; + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator. + //! + //! Effects: Inserts x into the container, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case) + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the internal value_compare ordering function throws. Strong guarantee. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_equal(const_iterator hint, reference value) + { + detail::key_nodeptr_comp + key_node_comp(this->comp(), &this->get_real_value_traits()); + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + iterator ret(node_algorithms::insert_equal + (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->real_value_traits_ptr()); + this->sz_traits().increment(); + return ret; + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Inserts a each element of a range into the container + //! before the upper bound of the key of each element. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_equal(Iterator b, Iterator e) + { + iterator iend(this->end()); + for (; b != e; ++b) + this->insert_equal(iend, *b); + } + + //! Requires: value must be an lvalue + //! + //! Effects: Inserts value into the container if the value + //! is not already present. + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + std::pair insert_unique(reference value) + { + insert_commit_data commit_data; + std::pair ret = this->insert_unique_check(value, this->comp(), commit_data); + if(!ret.second) + return ret; + return std::pair (this->insert_unique_commit(value, commit_data), true); + } + + //! Requires: value must be an lvalue, and "hint" must be + //! a valid iterator + //! + //! Effects: Tries to insert x into the container, using "hint" as a hint + //! to where it will be inserted. + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time (two comparisons in the worst case) + //! if t is inserted immediately before hint. + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + iterator insert_unique(const_iterator hint, reference value) + { + insert_commit_data commit_data; + std::pair ret = this->insert_unique_check(hint, value, this->comp(), commit_data); + if(!ret.second) + return ret.first; + return this->insert_unique_commit(value, commit_data); + } + + //! Requires: Dereferencing iterator must yield an lvalue + //! of type value_type. + //! + //! Effects: Tries to insert each element of a range into the container. + //! + //! Complexity: Insert range is in general O(N * log(N)), where N is the + //! size of the range. However, it is linear in N if the range is already sorted + //! by value_comp(). + //! + //! Throws: Nothing. + //! + //! Note: Does not affect the validity of iterators and references. + //! No copy-constructors are called. + template + void insert_unique(Iterator b, Iterator e) + { + if(this->empty()){ + iterator iend(this->end()); + for (; b != e; ++b) + this->insert_unique(iend, *b); + } + else{ + for (; b != e; ++b) + this->insert_unique(*b); + } + } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + template + std::pair insert_unique_check + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data); + + //! Requires: key_value_comp must be a comparison function that induces + //! the same strict weak ordering as value_compare. The difference is that + //! key_value_comp compares an arbitrary key with the contained values. + //! + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the key_value_comp ordering function throws. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + template + std::pair insert_unique_check + (const_iterator hint, const KeyType &key + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! Requires: value must be an lvalue of type value_type. commit_data + //! must have been obtained from a previous call to "insert_check". + //! No objects should have been inserted or erased from the container between + //! the "insert_check" that filled "commit_data" and the call to "insert_commit". + //! + //! Effects: Inserts the value in the container using the information obtained + //! from the "commit_data" that a previous "insert_check" filled. + //! + //! Returns: An iterator to the newly inserted object. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function has only sense if a "insert_check" has been + //! previously executed to fill "commit_data". No value should be inserted or + //! erased between the "insert_check" and "insert_commit" calls. + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) + { + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + node_algorithms::insert_unique_commit + (this->header_ptr(), to_insert, commit_data); + this->sz_traits().increment(); + return iterator(to_insert, this->real_value_traits_ptr()); + } + + //! Requires: value must be an lvalue, "pos" must be + //! a valid iterator (or end) and must be the succesor of value + //! once inserted according to the predicate + //! + //! Effects: Inserts x into the container before "pos". + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if "pos" is not + //! the successor of "value" container ordering invariant will be broken. + //! This is a low-level function to be used only for performance reasons + //! by advanced users. + iterator insert_before(const_iterator pos, reference value) + { + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->sz_traits().increment(); + return iterator(node_algorithms::insert_before + (this->header_ptr(), pos.pointed_node(), to_insert), this->real_value_traits_ptr()); + } + + //! Requires: value must be an lvalue, and it must be no less + //! than the greatest inserted key + //! + //! Effects: Inserts x into the container in the last position. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if value is + //! less than the greatest inserted key container ordering invariant will be broken. + //! This function is slightly more efficient than using "insert_before". + //! This is a low-level function to be used only for performance reasons + //! by advanced users. + void push_back(reference value) + { + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->sz_traits().increment(); + node_algorithms::push_back(this->header_ptr(), to_insert); + } + + //! Requires: value must be an lvalue, and it must be no greater + //! than the minimum inserted key + //! + //! Effects: Inserts x into the container in the first position. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. + //! + //! Note: This function does not check preconditions so if value is + //! greater than the minimum inserted key container ordering invariant will be broken. + //! This function is slightly more efficient than using "insert_before". + //! This is a low-level function to be used only for performance reasons + //! by advanced users. + void push_front(reference value) + { + node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value)); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); + this->sz_traits().increment(); + node_algorithms::push_front(this->header_ptr(), to_insert); + } + + //! Effects: Erases the element pointed to by pos. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(const_iterator i) + { + const_iterator ret(i); + ++ret; + node_ptr to_erase(i.pointed_node()); + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); + node_algorithms::erase(this->header_ptr(), to_erase); + this->sz_traits().decrement(); + if(safemode_or_autounlink) + node_algorithms::init(to_erase); + return ret.unconst(); + } + + //! Effects: Erases the range pointed to by b end e. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + iterator erase(const_iterator b, const_iterator e) + { size_type n; return this->private_erase(b, e, n); } + + //! Effects: Erases all the elements with the given value. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + size_type erase(const_reference value) + { return this->erase(value, this->comp()); } + + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase(const KeyType& key, KeyValueCompare comp + /// @cond + , typename detail::enable_if_c::value >::type * = 0 + /// @endcond + ) + { + std::pair p = this->equal_range(key, comp); + size_type n; + this->private_erase(p.first, p.second, n); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the element pointed to by pos. + //! Disposer::operator()(pointer) is called for the removed element. + //! + //! Complexity: Average complexity for erase element is constant time. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(const_iterator i, Disposer disposer) + { + node_ptr to_erase(i.pointed_node()); + iterator ret(this->erase(i)); + disposer(this->get_real_value_traits().to_value_ptr(to_erase)); + return ret; + } + + #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template + iterator erase_and_dispose(iterator i, Disposer disposer) + { return this->erase_and_dispose(const_iterator(i), disposer); } + #endif + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given value. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + template + size_type erase_and_dispose(const_reference value, Disposer disposer) + { + std::pair p = this->equal_range(value); + size_type n; + this->private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases the range pointed to by b end e. + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Complexity: Average complexity for erase range is at most + //! O(log(size() + N)), where N is the number of elements in the range. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { size_type n; return this->private_erase(b, e, n, disposer); } + + //! Requires: Disposer::operator()(pointer) shouldn't throw. + //! + //! Effects: Erases all the elements with the given key. + //! according to the comparison functor "comp". + //! Disposer::operator()(pointer) is called for the removed elements. + //! + //! Returns: The number of erased elements. + //! + //! Complexity: O(log(size() + N). + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators + //! to the erased elements. + template + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer + /// @cond + , typename detail::enable_if_c::value >::type * = 0 + /// @endcond + ) + { + std::pair p = this->equal_range(key, comp); + size_type n; + this->private_erase(p.first, p.second, n, disposer); + return n; + } + + //! Effects: Erases all of the elements. + //! + //! Complexity: Linear to the number of elements on the container. + //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. No destructors are called. + void clear() + { + if(safemode_or_autounlink){ + this->clear_and_dispose(detail::null_disposer()); + } + else{ + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(0); + } + } + + //! Effects: Erases all of the elements calling disposer(p) for + //! each node to be erased. + //! Complexity: Average complexity for is at most O(log(size() + N)), + //! where N is the number of elements in the container. + //! + //! Throws: Nothing. + //! + //! Note: Invalidates the iterators (but not the references) + //! to the erased elements. Calls N times to disposer functor. + template + void clear_and_dispose(Disposer disposer) + { + node_algorithms::clear_and_dispose(this->header_ptr() + , detail::node_disposer(disposer, &this->get_real_value_traits())); + node_algorithms::init_header(this->header_ptr()); + this->sz_traits().set_size(0); + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Returns the number of contained elements with the given value + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given value. + //! + //! Throws: Nothing. + size_type count(const_reference value) const; + + //! Effects: Returns the number of contained elements with the given key + //! + //! Complexity: Logarithmic to the number of elements contained plus lineal + //! to number of objects with the given key. + //! + //! Throws: Nothing. + template + size_type count(const KeyType &key, KeyValueCompare comp) const; + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator lower_bound(const_reference value); + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator lower_bound(const_reference value) const; + + //! Effects: Returns an iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator lower_bound(const KeyType &key, KeyValueCompare comp); + + //! Effects: Returns a const iterator to the first element whose + //! key is not less than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const; + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator upper_bound(const_reference value); + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator upper_bound(const KeyType &key, KeyValueCompare comp); + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator upper_bound(const_reference value) const; + + //! Effects: Returns an iterator to the first element whose + //! key is greater than k according to comp or end() if that element + //! does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const; + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + iterator find(const_reference value); + + //! Effects: Finds an iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + iterator find(const KeyType &key, KeyValueCompare comp); + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + const_iterator find(const_reference value) const; + + //! Effects: Finds a const_iterator to the first element whose key is + //! k or end() if that element does not exist. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + const_iterator find(const KeyType &key, KeyValueCompare comp) const; + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair equal_range(const_reference value); + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair equal_range(const KeyType &key, KeyValueCompare comp); + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + std::pair + equal_range(const_reference value) const; + + //! Effects: Finds a range containing all elements whose key is k or + //! an empty range that indicates the position where those elements would be + //! if they there is no elements with key k. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + template + std::pair + equal_range(const KeyType &key, KeyValueCompare comp) const; + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + //! + //! Note: Experimental function, the interface might change in future releases. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed); + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the container. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + //! + //! Note: Experimental function, the interface might change in future releases. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed); + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + //! + //! Note: Experimental function, the interface might change in future releases. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const; + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the container. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + //! + //! Note: Experimental function, the interface might change in future releases. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const; + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static iterator s_iterator_to(reference value); + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This static function is available only if the value traits + //! is stateless. + static const_iterator s_iterator_to(const_reference value); + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid iterator i belonging to the set + //! that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + iterator iterator_to(reference value); + + //! Requires: value must be an lvalue and shall be in a set of + //! appropriate type. Otherwise the behavior is undefined. + //! + //! Effects: Returns: a valid const_iterator i belonging to the + //! set that points to the value + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + const_iterator iterator_to(const_reference value) const; + + //! Requires: value shall not be in a container. + //! + //! Effects: init_node puts the hook of a value in a well-known default + //! state. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + //! + //! Note: This function puts the hook in the well-known default state + //! used by auto_unlink and safe hooks. + static void init_node(reference value); + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Unlinks the leftmost node from the container. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + //! + //! Notes: This function breaks the container and the container can + //! only be used for more unlink_leftmost_without_rebalance calls. + //! This function is normally used to achieve a step by step + //! controlled destruction of the container. + pointer unlink_leftmost_without_rebalance() + { + node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance + (this->header_ptr())); + if(!to_be_disposed) + return 0; + this->sz_traits().decrement(); + if(safemode_or_autounlink)//If this is commented does not work with normal_link + node_algorithms::init(to_be_disposed); + return this->get_real_value_traits().to_value_ptr(to_be_disposed); + } + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Requires: replace_this must be a valid iterator of *this + //! and with_this must not be inserted in any container. + //! + //! Effects: Replaces replace_this in its position in the + //! container with with_this. The container does not need to be rebalanced. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + //! + //! Note: This function will break container ordering invariants if + //! with_this is not equivalent to *replace_this according to the + //! ordering rules. This function is faster than erasing and inserting + //! the node, since no rebalancing or comparison is needed. + void replace_node(iterator replace_this, reference with_this); + + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + void rebalance(); + + //! Requires: old_root is a node of a tree. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements in the subtree. + iterator rebalance_subtree(iterator root); + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: removes "value" from the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Logarithmic time. + //! + //! Note: This static function is only usable with non-constant + //! time size containers that have stateless comparison functors. + //! + //! If the user calls + //! this function with a constant time size container or stateful comparison + //! functor a compilation error will be issued. + static void remove_node(reference value) + { + BOOST_STATIC_ASSERT((!constant_time_size)); + node_ptr to_remove(value_traits::to_node_ptr(value)); + node_algorithms::unlink(to_remove); + if(safemode_or_autounlink) + node_algorithms::init(to_remove); + } + + /// @cond + private: + template + iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) + { + for(n = 0; b != e; ++n) + this->erase_and_dispose(b++, disposer); + return b.unconst(); + } + + iterator private_erase(const_iterator b, const_iterator e, size_type &n) + { + for(n = 0; b != e; ++n) + this->erase(b++); + return b.unconst(); + } + /// @endcond + + private: + static bstree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) + { + return *static_cast + (boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())); + } +}; + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline bool operator< +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +bool operator== +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ + typedef bstree_impl tree_type; + typedef typename tree_type::const_iterator const_iterator; + + if(tree_type::constant_time_size && x.size() != y.size()){ + return false; + } + const_iterator end1 = x.end(); + const_iterator i1 = x.begin(); + const_iterator i2 = y.begin(); + if(tree_type::constant_time_size){ + while (i1 != end1 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1; + } + else{ + const_iterator end2 = y.end(); + while (i1 != end1 && i2 != end2 && *i1 == *i2) { + ++i1; + ++i2; + } + return i1 == end1 && i2 == end2; + } +} + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline bool operator!= +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ return !(x == y); } + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline bool operator> +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ return y < x; } + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline bool operator<= +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ return !(y < x); } + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline bool operator>= +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(const bstree_impl &x, const bstree_impl &y) +#else +( const bstree_impl &x +, const bstree_impl &y) +#endif +{ return !(x < y); } + +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +template +#else +template +#endif +inline void swap +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) +(bstree_impl &x, bstree_impl &y) +#else +( bstree_impl &x +, bstree_impl &y) +#endif +{ x.swap(y); } + +//! Helper metafunction to define a \c bstree that yields to the same type when the +//! same options (either explicitly or implicitly) are used. +#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct make_bstree +{ + /// @cond + typedef typename pack_options + < bstree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef bstree_impl + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + , BsTreeAlgorithms + > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template +#else +template +#endif +class bstree + : public make_bstree::type +{ + typedef typename make_bstree + ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree) + + public: + typedef typename Base::value_compare value_compare; + typedef typename Base::value_traits value_traits; + typedef typename Base::real_value_traits real_value_traits; + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + + //Assert if passed value traits are compatible with the type + BOOST_STATIC_ASSERT((detail::is_same::value)); + + bstree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(cmp, v_traits) + {} + + template + bstree( bool unique, Iterator b, Iterator e + , const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) + : Base(unique, b, e, cmp, v_traits) + {} + + bstree(BOOST_RV_REF(bstree) x) + : Base(::boost::move(static_cast(x))) + {} + + bstree& operator=(BOOST_RV_REF(bstree) x) + { return static_cast(this->Base::operator=(::boost::move(static_cast(x)))); } + + static bstree &container_from_end_iterator(iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static const bstree &container_from_end_iterator(const_iterator end_iterator) + { return static_cast(Base::container_from_end_iterator(end_iterator)); } + + static bstree &container_from_iterator(iterator it) + { return static_cast(Base::container_from_iterator(it)); } + + static const bstree &container_from_iterator(const_iterator it) + { return static_cast(Base::container_from_iterator(it)); } +}; + +#endif +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_BSTREE_HPP diff --git a/cpp/BoostParts/boost/intrusive/detail/tree_algorithms.hpp b/cpp/BoostParts/boost/intrusive/bstree_algorithms.hpp similarity index 76% rename from cpp/BoostParts/boost/intrusive/detail/tree_algorithms.hpp rename to cpp/BoostParts/boost/intrusive/bstree_algorithms.hpp index 27c86673..62973292 100644 --- a/cpp/BoostParts/boost/intrusive/detail/tree_algorithms.hpp +++ b/cpp/BoostParts/boost/intrusive/bstree_algorithms.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -10,8 +10,8 @@ // ///////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP -#define BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP +#ifndef BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP #include #include @@ -22,7 +22,32 @@ namespace boost { namespace intrusive { -namespace detail { + +/// @cond + +//! This type is the information that will be filled by insert_unique_check +template +struct insert_commit_data_t +{ + insert_commit_data_t() + : link_left(false) + , node() + {} + bool link_left; + NodePtr node; +}; + +template +struct data_for_rebalance_t +{ + NodePtr x; + NodePtr x_parent; + NodePtr y; +}; + +/// @endcond + + //! This is an implementation of a binary search tree. //! A node in the search tree has references to its children and its parent. This @@ -66,14 +91,13 @@ namespace detail { //! | | | | | | | | //! +---------+ +---------+ +---------+ +---------+ //! - -//! tree_algorithms is configured with a NodeTraits class, which encapsulates the +//! bstree_algorithms is configured with a NodeTraits class, which encapsulates the //! information about the node to be manipulated. NodeTraits must support the //! following interface: //! //! Typedefs: //! -//! node: The type of the node that forms the circular list +//! node: The type of the node that forms the binary search tree //! //! node_ptr: A pointer to a node //! @@ -93,31 +117,18 @@ namespace detail { //! //! static void set_right(node_ptr n, node_ptr right); template -class tree_algorithms +class bstree_algorithms { public: typedef typename NodeTraits::node node; typedef NodeTraits node_traits; typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; - - //! This type is the information that will be filled by insert_unique_check - struct insert_commit_data - { - insert_commit_data() - : link_left(false) - , node() - {} - bool link_left; - node_ptr node; - }; - - struct nop_erase_fixup - { - void operator()(const node_ptr&, const node_ptr&){} - }; + typedef insert_commit_data_t insert_commit_data; + typedef data_for_rebalance_t data_for_rebalance; /// @cond + private: template struct dispose_subtree_disposer @@ -136,20 +147,31 @@ class tree_algorithms } } Disposer *disposer_; - node_ptr subtree_; + const node_ptr subtree_; }; - static node_ptr uncast(const const_node_ptr & ptr) - { return pointer_traits::const_cast_from(ptr); } - /// @endcond public: + //! Requires: 'header' is the header node of a tree. + //! + //! Effects: Returns the first node of the tree, the header if the tree is empty. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. static node_ptr begin_node(const const_node_ptr & header) { return node_traits::get_left(header); } + //! Requires: 'header' is the header node of a tree. + //! + //! Effects: Returns the header of the tree. + //! + //! Complexity: Constant time. + //! + //! Throws: Nothing. static node_ptr end_node(const const_node_ptr & header) - { return uncast(header); } + { return detail::uncast(header); } //! Requires: 'node' is a node of the tree or an node initialized //! by init(...) or init_node. @@ -162,15 +184,48 @@ class tree_algorithms static bool unique(const const_node_ptr & node) { return !NodeTraits::get_parent(node); } + //! Requires: 'node' is a node of the tree or a header node. + //! + //! Effects: Returns the header of the tree. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. static node_ptr get_header(const const_node_ptr & node) { - node_ptr h = uncast(node); - if(NodeTraits::get_parent(node)){ - h = NodeTraits::get_parent(node); - while(!is_header(h)) - h = NodeTraits::get_parent(h); + node_ptr n(detail::uncast(node)); + node_ptr p(NodeTraits::get_parent(node)); + //If p is null, then n is the header of an empty tree + if(p){ + //Non-empty tree, check if n is neither root nor header + node_ptr pp(NodeTraits::get_parent(p)); + //If granparent is not equal to n, then n is neither root nor header, + //the try the fast path + if(n != pp){ + do{ + n = p; + p = pp; + pp = NodeTraits::get_parent(pp); + }while(n != pp); + n = p; + } + //Check if n is root or header when size() > 0 + else if(!is_header(n)){ + n = p; + } } - return h; + return n; + /* + node_ptr h = detail::uncast(node); + node_ptr p = NodeTraits::get_parent(node); + if(p){ + while(!is_header(p)) + p = NodeTraits::get_parent(p); + return p; + } + else{ + return h; + }*/ } //! Requires: node1 and node2 can't be header nodes @@ -358,9 +413,7 @@ class tree_algorithms //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing and comparison is needed. - //! - //!Experimental function + //! the node, since no rebalancing and comparison is needed. Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) { if(node_to_be_replaced == new_node) @@ -381,9 +434,7 @@ class tree_algorithms //! Note: This function will break container ordering invariants if //! new_node is not equivalent to node_to_be_replaced according to the //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing or comparison is needed. - //! - //!Experimental function + //! the node, since no rebalancing or comparison is needed. Experimental function static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) { if(node_to_be_replaced == new_node) @@ -447,7 +498,7 @@ class tree_algorithms p = x; x = NodeTraits::get_parent(x); } - return NodeTraits::get_right(p) != x ? x : uncast(p); + return NodeTraits::get_right(p) != x ? x : detail::uncast(p); } } @@ -602,7 +653,7 @@ class tree_algorithms if (leftmost_right){ NodeTraits::set_parent(leftmost_right, leftmost_parent); - NodeTraits::set_left(header, tree_algorithms::minimum(leftmost_right)); + NodeTraits::set_left(header, bstree_algorithms::minimum(leftmost_right)); if (is_root) NodeTraits::set_parent(header, leftmost_right); @@ -621,42 +672,6 @@ class tree_algorithms return leftmost; } - //! Requires: node is a node of the tree but it's not the header. - //! - //! Effects: Returns the number of nodes of the subtree. - //! - //! Complexity: Linear time. - //! - //! Throws: Nothing. - static std::size_t count(const const_node_ptr & subtree) - { - if(!subtree) return 0; - std::size_t count = 0; - node_ptr p = minimum(uncast(subtree)); - bool continue_looping = true; - while(continue_looping){ - ++count; - node_ptr p_right(NodeTraits::get_right(p)); - if(p_right){ - p = minimum(p_right); - } - else { - for(;;){ - node_ptr q; - if (p == subtree){ - continue_looping = false; - break; - } - q = p; - p = NodeTraits::get_parent(p); - if (NodeTraits::get_left(p) == q) - break; - } - } - } - return count; - } - //! Requires: node is a node of the tree but it's not the header. //! //! Effects: Returns the number of nodes of the subtree. @@ -722,6 +737,13 @@ class tree_algorithms } } + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is the header of the tree. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. static bool is_header(const const_node_ptr & p) { node_ptr p_left (NodeTraits::get_left(p)); @@ -754,7 +776,7 @@ class tree_algorithms static node_ptr find (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - node_ptr end = uncast(header); + node_ptr end = detail::uncast(header); node_ptr y = lower_bound(header, key, comp); return (y == end || comp(key, y)) ? end : y; } @@ -778,6 +800,8 @@ class tree_algorithms //! //! Note: This function can be more efficient than calling upper_bound //! and lower_bound for lower_key and upper_key. + //! + //! Note: Experimental function, the interface might change. template< class KeyType, class KeyNodePtrCompare> static std::pair bounded_range ( const const_node_ptr & header @@ -787,7 +811,7 @@ class tree_algorithms , bool left_closed , bool right_closed) { - node_ptr y = uncast(header); + node_ptr y = detail::uncast(header); node_ptr x = NodeTraits::get_parent(header); while(x){ @@ -835,6 +859,30 @@ class tree_algorithms return std::pair (y, y); } + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns the number of elements with a key equivalent to "key"pair of node_ptr delimiting a range containing + //! according to "comp". + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::size_t count + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + { + std::pair ret = equal_range(header, key, comp); + std::size_t n = 0; + while(ret.first != ret.second){ + ++n; + ret.first = next_node(ret.first); + } + return n; + } + //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the @@ -871,7 +919,7 @@ class tree_algorithms static node_ptr lower_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - return lower_bound_loop(NodeTraits::get_parent(header), uncast(header), key, comp); + return lower_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } //! Requires: "header" must be the header node of a tree. @@ -889,7 +937,7 @@ class tree_algorithms static node_ptr upper_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - return upper_bound_loop(NodeTraits::get_parent(header), uncast(header), key, comp); + return upper_bound_loop(NodeTraits::get_parent(header), detail::uncast(header), key, comp); } //! Requires: "header" must be the header node of a tree. @@ -913,32 +961,6 @@ class tree_algorithms (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) { return insert_commit(header, new_value, commit_data); } - static void insert_commit - (const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data) - { - //Check if commit_data has not been initialized by a insert_unique_check call. - BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != node_ptr()); - node_ptr parent_node(commit_data.node); - if(parent_node == header){ - NodeTraits::set_parent(header, new_node); - NodeTraits::set_right(header, new_node); - NodeTraits::set_left(header, new_node); - } - else if(commit_data.link_left){ - NodeTraits::set_left(parent_node, new_node); - if(parent_node == NodeTraits::get_left(header)) - NodeTraits::set_left(header, new_node); - } - else{ - NodeTraits::set_right(parent_node, new_node); - if(parent_node == NodeTraits::get_right(header)) - NodeTraits::set_right(header, new_node); - } - NodeTraits::set_parent(new_node, parent_node); - NodeTraits::set_right(new_node, node_ptr()); - NodeTraits::set_left(new_node, node_ptr()); - } - //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the @@ -975,11 +997,15 @@ class tree_algorithms //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check - (const const_node_ptr & header, const KeyType &key - ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) + (const const_node_ptr & header, const KeyType &key + ,KeyNodePtrCompare comp, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { std::size_t depth = 0; - node_ptr h(uncast(header)); + node_ptr h(detail::uncast(header)); node_ptr y(h); node_ptr x(NodeTraits::get_parent(y)); node_ptr prev = node_ptr(); @@ -1011,10 +1037,53 @@ class tree_algorithms } } + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares KeyType with a node_ptr. + //! "hint" is node from the "header"'s tree. + //! + //! Effects: Checks if there is an equivalent node to "key" in the + //! tree according to "comp" using "hint" as a hint to where it should be + //! inserted and obtains the needed information to realize + //! a constant-time node insertion if there is no equivalent node. + //! If "hint" is the upper_bound the function has constant time + //! complexity (two comparisons in the worst case). + //! + //! Returns: If there is an equivalent value + //! returns a pair containing a node_ptr to the already present node + //! and false. If there is not equivalent key can be inserted returns true + //! in the returned pair's boolean and fills "commit_data" that is meant to + //! be used with the "insert_commit" function to achieve a constant-time + //! insertion function. + //! + //! Complexity: Average complexity is at most logarithmic, but it is + //! amortized constant time if new_node should be inserted immediately before "hint". + //! + //! Throws: If "comp" throws. + //! + //! Notes: This function is used to improve performance when constructing + //! a node is expensive and the user does not want to have two equivalent nodes + //! in the tree: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the node and this function offers the possibility to use that part + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the node and use + //! "insert_commit" to insert the node in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_unique_commit" only + //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check (const const_node_ptr & header, const node_ptr &hint, const KeyType &key - ,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0) + ,KeyNodePtrCompare comp, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { //hint must be bigger than the key if(hint == header || comp(key, hint)){ @@ -1033,44 +1102,27 @@ class tree_algorithms return insert_unique_check(header, key, comp, commit_data, pdepth); } - template - static void insert_equal_check - (const node_ptr &header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp - , insert_commit_data &commit_data, std::size_t *pdepth = 0) - { - if(hint == header || !comp(hint, new_node)){ - node_ptr prev(hint); - if(hint == NodeTraits::get_left(header) || - !comp(new_node, (prev = prev_node(hint)))){ - bool link_left = unique(header) || !NodeTraits::get_left(hint); - commit_data.link_left = link_left; - commit_data.node = link_left ? hint : prev; - if(pdepth){ - *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; - } - } - else{ - insert_equal_upper_bound_check(header, new_node, comp, commit_data, pdepth); - } - } - else{ - insert_equal_lower_bound_check(header, new_node, comp, commit_data, pdepth); - } - } - - template - static void insert_equal_upper_bound_check - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) - { insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); } - - template - static void insert_equal_lower_bound_check - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) - { insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); } - + //! Requires: "header" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from + //! the "header"'s tree. + //! + //! Effects: Inserts new_node into the tree, using "hint" as a hint to + //! where it will be inserted. If "hint" is the upper_bound + //! the insertion takes constant time (two comparisons in the worst case). + //! + //! Complexity: Logarithmic in general, but it is amortized + //! constant time if new_node is inserted immediately before "hint". + //! + //! Throws: If "comp" throws. template static node_ptr insert_equal - (const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + (const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; insert_equal_check(h, hint, new_node, comp, commit_data, pdepth); @@ -1078,9 +1130,25 @@ class tree_algorithms return new_node; } + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the upper bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. template static node_ptr insert_equal_upper_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth); @@ -1088,9 +1156,25 @@ class tree_algorithms return new_node; } + //! Requires: "h" must be the header node of a tree. + //! NodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. NodePtrCompare compares two node_ptrs. + //! + //! Effects: Inserts new_node into the tree before the lower bound + //! according to "comp". + //! + //! Complexity: Average complexity for insert element is at + //! most logarithmic. + //! + //! Throws: If "comp" throws. template static node_ptr insert_equal_lower_bound - (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0) + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth); @@ -1098,8 +1182,26 @@ class tree_algorithms return new_node; } + //! Requires: "header" must be the header node of a tree. + //! "pos" must be a valid iterator or header (end) node. + //! "pos" must be an iterator pointing to the successor to "new_node" + //! once inserted according to the order of already inserted nodes. This function does not + //! check "pos" and this precondition must be guaranteed by the caller. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "pos" is not the successor of the newly inserted "new_node" + //! tree invariants might be broken. static node_ptr insert_before - (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node, std::size_t *pdepth = 0) + (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; insert_before_check(header, pos, commit_data, pdepth); @@ -1107,59 +1209,56 @@ class tree_algorithms return new_node; } - static void insert_before_check - (const node_ptr &header, const node_ptr & pos - , insert_commit_data &commit_data, std::size_t *pdepth = 0) - { - node_ptr prev(pos); - if(pos != NodeTraits::get_left(header)) - prev = prev_node(pos); - bool link_left = unique(header) || !NodeTraits::get_left(pos); - commit_data.link_left = link_left; - commit_data.node = link_left ? pos : prev; - if(pdepth){ - *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; - } - } - + //! Requires: "header" must be the header node of a tree. + //! "new_node" must be, according to the used ordering no less than the + //! greatest inserted key. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "new_node" is less than the greatest inserted key + //! tree invariants are broken. This function is slightly faster than + //! using "insert_before". static void push_back - (const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0) + (const node_ptr & header, const node_ptr & new_node + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; push_back_check(header, commit_data, pdepth); insert_commit(header, new_node, commit_data); } - static void push_back_check - (const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0) - { - node_ptr prev(NodeTraits::get_right(header)); - if(pdepth){ - *pdepth = prev == header ? 0 : depth(prev) + 1; - } - commit_data.link_left = false; - commit_data.node = prev; - } - + //! Requires: "header" must be the header node of a tree. + //! "new_node" must be, according to the used ordering, no greater than the + //! lowest inserted key. + //! + //! Effects: Inserts new_node into the tree before "pos". + //! + //! Complexity: Constant-time. + //! + //! Throws: Nothing. + //! + //! Note: If "new_node" is greater than the lowest inserted key + //! tree invariants are broken. This function is slightly faster than + //! using "insert_before". static void push_front - (const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0) + (const node_ptr & header, const node_ptr & new_node + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) { insert_commit_data commit_data; push_front_check(header, commit_data, pdepth); insert_commit(header, new_node, commit_data); } - static void push_front_check - (const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0) - { - node_ptr pos(NodeTraits::get_left(header)); - if(pdepth){ - *pdepth = pos == header ? 0 : depth(pos) + 1; - } - commit_data.link_left = true; - commit_data.node = pos; - } - //! Requires: 'node' can't be a header node. //! //! Effects: Calculates the depth of a node: the depth of a @@ -1215,6 +1314,442 @@ class tree_algorithms NodeTraits::set_right (target_header, rightmost); } + //! Requires: header must be the header of a tree, z a node + //! of that tree and z != header. + //! + //! Effects: Erases node "z" from the tree with header "header". + //! + //! Complexity: Amortized constant time. + //! + //! Throws: Nothing. + static void erase(const node_ptr & header, const node_ptr & z) + { + data_for_rebalance ignored; + erase_impl(header, z, ignored); + } + + //! Requires: node is a tree node but not the header. + //! + //! Effects: Unlinks the node and rebalances the tree. + //! + //! Complexity: Average complexity is constant time. + //! + //! Throws: Nothing. + static void unlink(const node_ptr & node) + { + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)) + x = NodeTraits::get_parent(x); + erase(x, node); + } + } + + //! Requires: header must be the header of a tree. + //! + //! Effects: Rebalances the tree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static void rebalance(const node_ptr & header) + { + node_ptr root = NodeTraits::get_parent(header); + if(root){ + rebalance_subtree(root); + } + } + + //! Requires: old_root is a node of a tree. It shall not be null. + //! + //! Effects: Rebalances the subtree rooted at old_root. + //! + //! Returns: The new root of the subtree. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear. + static node_ptr rebalance_subtree(const node_ptr & old_root) + { + //Taken from: + //"Tree rebalancing in optimal time and space" + //Quentin F. Stout and Bette L. Warren + + //To avoid irregularities in the algorithm (old_root can be a + //left or right child or even the root of the tree) just put the + //root as the right child of its parent. Before doing this backup + //information to restore the original relationship after + //the algorithm is applied. + node_ptr super_root = NodeTraits::get_parent(old_root); + BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root); + + //Get root info + node_ptr super_root_right_backup = NodeTraits::get_right(super_root); + bool super_root_is_header = NodeTraits::get_parent(super_root) == old_root; + bool old_root_is_right = is_right_child(old_root); + NodeTraits::set_right(super_root, old_root); + + std::size_t size; + subtree_to_vine(super_root, size); + vine_to_subtree(super_root, size); + node_ptr new_root = NodeTraits::get_right(super_root); + + //Recover root + if(super_root_is_header){ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_parent(super_root, new_root); + } + else if(old_root_is_right){ + NodeTraits::set_right(super_root, new_root); + } + else{ + NodeTraits::set_right(super_root, super_root_right_backup); + NodeTraits::set_left(super_root, new_root); + } + return new_root; + } + + protected: + //! Requires: node is a node of the tree but it's not the header. + //! + //! Effects: Returns the number of nodes of the subtree. + //! + //! Complexity: Linear time. + //! + //! Throws: Nothing. + static std::size_t subtree_size(const const_node_ptr & subtree) + { + std::size_t count = 0; + if (subtree){ + node_ptr n = detail::uncast(subtree); + node_ptr m = NodeTraits::get_left(n); + while(m){ + n = m; + m = NodeTraits::get_left(n); + } + + while(1){ + ++count; + node_ptr n_right(NodeTraits::get_right(n)); + if(n_right){ + n = n_right; + m = NodeTraits::get_left(n); + while(m){ + n = m; + m = NodeTraits::get_left(n); + } + } + else { + do{ + if (n == subtree){ + return count; + } + m = n; + n = NodeTraits::get_parent(n); + }while(NodeTraits::get_left(n) != m); + } + } + } + return count; + } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is a left child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_left_child(const node_ptr & p) + { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } + + //! Requires: p is a node of a tree. + //! + //! Effects: Returns true if p is a right child. + //! + //! Complexity: Constant. + //! + //! Throws: Nothing. + static bool is_right_child(const node_ptr & p) + { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } + + template + static void erase(const node_ptr & header, const node_ptr & z, F z_and_successor_fixup, data_for_rebalance &info) + { + erase_impl(header, z, info); + if(info.y != z){ + z_and_successor_fixup(z, info.y); + } + } + + //Fix header and own's parent data when replacing x with own, providing own's old data with parent + static void replace_own_impl(const node_ptr & own, const node_ptr & x, const node_ptr & header, const node_ptr & own_parent, bool own_was_left) + { + if(NodeTraits::get_parent(header) == own) + NodeTraits::set_parent(header, x); + else if(own_was_left) + NodeTraits::set_left(own_parent, x); + else + NodeTraits::set_right(own_parent, x); + } + + //Fix header and own's parent data when replacing x with own, supposing own + //links with its parent are still ok + static void replace_own(const node_ptr & own, const node_ptr & x, const node_ptr & header) + { + node_ptr own_parent(NodeTraits::get_parent(own)); + bool own_is_left(NodeTraits::get_left(own_parent) == own); + replace_own_impl(own, x, header, own_parent, own_is_left); + } + + // rotate parent p to left (no header and p's parent fixup) + static node_ptr rotate_left(const node_ptr & p) + { + node_ptr x(NodeTraits::get_right(p)); + node_ptr x_left(NodeTraits::get_left(x)); + NodeTraits::set_right(p, x_left); + if(x_left){ + NodeTraits::set_parent(x_left, p); + } + NodeTraits::set_left(x, p); + NodeTraits::set_parent(p, x); + return x; + } + + // rotate parent p to left (with header and p's parent fixup) + static void rotate_left(const node_ptr & p, const node_ptr & header) + { + bool p_was_left(is_left_child(p)); + node_ptr p_old_parent(NodeTraits::get_parent(p)); + node_ptr x(rotate_left(p)); + NodeTraits::set_parent(x, p_old_parent); + replace_own_impl(p, x, header, p_old_parent, p_was_left); + } + + // rotate parent p to right (no header and p's parent fixup) + static node_ptr rotate_right(const node_ptr & p) + { + node_ptr x(NodeTraits::get_left(p)); + node_ptr x_right(NodeTraits::get_right(x)); + NodeTraits::set_left(p, x_right); + if(x_right){ + NodeTraits::set_parent(x_right, p); + } + NodeTraits::set_right(x, p); + NodeTraits::set_parent(p, x); + return x; + } + + // rotate parent p to right (with header and p's parent fixup) + static void rotate_right(const node_ptr & p, const node_ptr & header) + { + bool p_was_left(is_left_child(p)); + node_ptr p_old_parent(NodeTraits::get_parent(p)); + node_ptr x(rotate_right(p)); + NodeTraits::set_parent(x, p_old_parent); + replace_own_impl(p, x, header, p_old_parent, p_was_left); + } + + static void insert_before_check + (const node_ptr &header, const node_ptr & pos + , insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + node_ptr prev(pos); + if(pos != NodeTraits::get_left(header)) + prev = prev_node(pos); + bool link_left = unique(header) || !NodeTraits::get_left(pos); + commit_data.link_left = link_left; + commit_data.node = link_left ? pos : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + } + + static void push_back_check + (const node_ptr & header, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + node_ptr prev(NodeTraits::get_right(header)); + if(pdepth){ + *pdepth = prev == header ? 0 : depth(prev) + 1; + } + commit_data.link_left = false; + commit_data.node = prev; + } + + static void push_front_check + (const node_ptr & header, insert_commit_data &commit_data + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + , std::size_t *pdepth = 0 + #endif + ) + { + node_ptr pos(NodeTraits::get_left(header)); + if(pdepth){ + *pdepth = pos == header ? 0 : depth(pos) + 1; + } + commit_data.link_left = true; + commit_data.node = pos; + } + + template + static void insert_equal_check + (const node_ptr &header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp + , insert_commit_data &commit_data + /// @cond + , std::size_t *pdepth = 0 + /// @endcond + ) + { + if(hint == header || !comp(hint, new_node)){ + node_ptr prev(hint); + if(hint == NodeTraits::get_left(header) || + !comp(new_node, (prev = prev_node(hint)))){ + bool link_left = unique(header) || !NodeTraits::get_left(hint); + commit_data.link_left = link_left; + commit_data.node = link_left ? hint : prev; + if(pdepth){ + *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1; + } + } + else{ + insert_equal_upper_bound_check(header, new_node, comp, commit_data, pdepth); + } + } + else{ + insert_equal_lower_bound_check(header, new_node, comp, commit_data, pdepth); + } + } + + template + static void insert_equal_upper_bound_check + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + { insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); } + + template + static void insert_equal_lower_bound_check + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) + { insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); } + + static void insert_commit + (const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data) + { + //Check if commit_data has not been initialized by a insert_unique_check call. + BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != node_ptr()); + node_ptr parent_node(commit_data.node); + if(parent_node == header){ + NodeTraits::set_parent(header, new_node); + NodeTraits::set_right(header, new_node); + NodeTraits::set_left(header, new_node); + } + else if(commit_data.link_left){ + NodeTraits::set_left(parent_node, new_node); + if(parent_node == NodeTraits::get_left(header)) + NodeTraits::set_left(header, new_node); + } + else{ + NodeTraits::set_right(parent_node, new_node); + if(parent_node == NodeTraits::get_right(header)) + NodeTraits::set_right(header, new_node); + } + NodeTraits::set_parent(new_node, parent_node); + NodeTraits::set_right(new_node, node_ptr()); + NodeTraits::set_left(new_node, node_ptr()); + } + + private: + static void subtree_to_vine(node_ptr vine_tail, std::size_t &size) + { + //Inspired by LibAVL: + //It uses a clever optimization for trees with parent pointers. + //No parent pointer is updated when transforming a tree to a vine as + //most of them will be overriten during compression rotations. + //A final pass must be made after the rebalancing to updated those + //pointers not updated by tree_to_vine + compression calls + std::size_t len = 0; + node_ptr remainder = NodeTraits::get_right(vine_tail); + while(remainder){ + node_ptr tempptr = NodeTraits::get_left(remainder); + if(!tempptr){ //move vine-tail down one + vine_tail = remainder; + remainder = NodeTraits::get_right(remainder); + ++len; + } + else{ //rotate + NodeTraits::set_left(remainder, NodeTraits::get_right(tempptr)); + NodeTraits::set_right(tempptr, remainder); + remainder = tempptr; + NodeTraits::set_right(vine_tail, tempptr); + } + } + size = len; + } + + static void compress_subtree(node_ptr scanner, std::size_t count) + { + while(count--){ //compress "count" spine nodes in the tree with pseudo-root scanner + node_ptr child = NodeTraits::get_right(scanner); + node_ptr child_right = NodeTraits::get_right(child); + NodeTraits::set_right(scanner, child_right); + //Avoid setting the parent of child_right + scanner = child_right; + node_ptr scanner_left = NodeTraits::get_left(scanner); + NodeTraits::set_right(child, scanner_left); + if(scanner_left) + NodeTraits::set_parent(scanner_left, child); + NodeTraits::set_left(scanner, child); + NodeTraits::set_parent(child, scanner); + } + } + + static void vine_to_subtree(const node_ptr & super_root, std::size_t count) + { + std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << detail::floor_log2(count + 1)); + compress_subtree(super_root, leaf_nodes); //create deepest leaves + std::size_t vine_nodes = count - leaf_nodes; + while(vine_nodes > 1){ + vine_nodes /= 2; + compress_subtree(super_root, vine_nodes); + } + + //Update parents of nodes still in the in the original vine line + //as those have not been updated by subtree_to_vine or compress_subtree + for ( node_ptr q = super_root, p = NodeTraits::get_right(super_root) + ; p + ; q = p, p = NodeTraits::get_right(p)){ + NodeTraits::set_parent(p, q); + } + } + + //! Requires: "n" must be a node inserted in a tree. + //! + //! Effects: Returns a pointer to the header node of the tree. + //! + //! Complexity: Logarithmic. + //! + //! Throws: Nothing. + static node_ptr get_root(const node_ptr & node) + { + BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node))); + node_ptr x = NodeTraits::get_parent(node); + if(x){ + while(!is_header(x)){ + x = NodeTraits::get_parent(x); + } + return x; + } + else{ + return node; + } + } + template static node_ptr clone_subtree (const const_node_ptr &source_parent, const node_ptr &target_parent @@ -1310,304 +1845,6 @@ class tree_algorithms } } - //! Requires: p is a node of a tree. - //! - //! Effects: Returns true if p is a left child. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - static bool is_left_child(const node_ptr & p) - { return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; } - - //! Requires: p is a node of a tree. - //! - //! Effects: Returns true if p is a right child. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - static bool is_right_child(const node_ptr & p) - { return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; } - - //Fix header and own's parent data when replacing x with own, providing own's old data with parent - static void replace_own_impl(const node_ptr & own, const node_ptr & x, const node_ptr & header, const node_ptr & own_parent, bool own_was_left) - { - if(NodeTraits::get_parent(header) == own) - NodeTraits::set_parent(header, x); - else if(own_was_left) - NodeTraits::set_left(own_parent, x); - else - NodeTraits::set_right(own_parent, x); - } - - //Fix header and own's parent data when replacing x with own, supposing own - //links with its parent are still ok - static void replace_own(const node_ptr & own, const node_ptr & x, const node_ptr & header) - { - node_ptr own_parent(NodeTraits::get_parent(own)); - bool own_is_left(NodeTraits::get_left(own_parent) == own); - replace_own_impl(own, x, header, own_parent, own_is_left); - } - - // rotate parent p to left (no header and p's parent fixup) - static node_ptr rotate_left(const node_ptr & p) - { - node_ptr x(NodeTraits::get_right(p)); - node_ptr x_left(NodeTraits::get_left(x)); - NodeTraits::set_right(p, x_left); - if(x_left){ - NodeTraits::set_parent(x_left, p); - } - NodeTraits::set_left(x, p); - NodeTraits::set_parent(p, x); - return x; - } - - // rotate parent p to left (with header and p's parent fixup) - static void rotate_left(const node_ptr & p, const node_ptr & header) - { - bool p_was_left(is_left_child(p)); - node_ptr p_old_parent(NodeTraits::get_parent(p)); - node_ptr x(rotate_left(p)); - NodeTraits::set_parent(x, p_old_parent); - replace_own_impl(p, x, header, p_old_parent, p_was_left); - } - - // rotate parent p to right (no header and p's parent fixup) - static node_ptr rotate_right(const node_ptr & p) - { - node_ptr x(NodeTraits::get_left(p)); - node_ptr x_right(NodeTraits::get_right(x)); - NodeTraits::set_left(p, x_right); - if(x_right){ - NodeTraits::set_parent(x_right, p); - } - NodeTraits::set_right(x, p); - NodeTraits::set_parent(p, x); - return x; - } - - // rotate parent p to right (with header and p's parent fixup) - static void rotate_right(const node_ptr & p, const node_ptr & header) - { - bool p_was_left(is_left_child(p)); - node_ptr p_old_parent(NodeTraits::get_parent(p)); - node_ptr x(rotate_right(p)); - NodeTraits::set_parent(x, p_old_parent); - replace_own_impl(p, x, header, p_old_parent, p_was_left); - } - - static void erase(const node_ptr & header, const node_ptr & z) - { - data_for_rebalance ignored; - erase_impl(header, z, ignored); - } - - struct data_for_rebalance - { - node_ptr x; - node_ptr x_parent; - node_ptr y; - }; - - template - static void erase(const node_ptr & header, const node_ptr & z, F z_and_successor_fixup, data_for_rebalance &info) - { - erase_impl(header, z, info); - if(info.y != z){ - z_and_successor_fixup(z, info.y); - } - } - - static void unlink(const node_ptr & node) - { - node_ptr x = NodeTraits::get_parent(node); - if(x){ - while(!is_header(x)) - x = NodeTraits::get_parent(x); - erase(x, node); - } - } - - static void tree_to_vine(const node_ptr & header) - { subtree_to_vine(NodeTraits::get_parent(header)); } - - static void vine_to_tree(const node_ptr & header, std::size_t count) - { vine_to_subtree(NodeTraits::get_parent(header), count); } - - static void rebalance(const node_ptr & header) - { - //Taken from: - //"Tree rebalancing in optimal time and space" - //Quentin F. Stout and Bette L. Warren - std::size_t len = 0; - subtree_to_vine(NodeTraits::get_parent(header), &len); - vine_to_subtree(NodeTraits::get_parent(header), len); - } - - static node_ptr rebalance_subtree(const node_ptr & old_root) - { - std::size_t len = 0; - node_ptr new_root = subtree_to_vine(old_root, &len); - return vine_to_subtree(new_root, len); - } - - static node_ptr subtree_to_vine(const node_ptr & old_root, std::size_t *plen = 0) - { - std::size_t len; - len = 0; - if(!old_root) return node_ptr(); - - //To avoid irregularities in the algorithm (old_root can be a - //left or right child or even the root of the tree) just put the - //root as the right child of its parent. Before doing this backup - //information to restore the original relationship after - //the algorithm is applied. - node_ptr super_root = NodeTraits::get_parent(old_root); - BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root); - - //Get info - node_ptr super_root_right_backup = NodeTraits::get_right(super_root); - bool super_root_is_header = is_header(super_root); - bool old_root_is_right = is_right_child(old_root); - - node_ptr x(old_root); - node_ptr new_root(x); - node_ptr save; - bool moved_to_right = false; - for( ; x; x = save){ - save = NodeTraits::get_left(x); - if(save){ - // Right rotation - node_ptr save_right = NodeTraits::get_right(save); - node_ptr x_parent = NodeTraits::get_parent(x); - NodeTraits::set_parent(save, x_parent); - NodeTraits::set_right (x_parent, save); - NodeTraits::set_parent(x, save); - NodeTraits::set_right (save, x); - NodeTraits::set_left(x, save_right); - if(save_right) - NodeTraits::set_parent(save_right, x); - if(!moved_to_right) - new_root = save; - } - else{ - moved_to_right = true; - save = NodeTraits::get_right(x); - ++len; - } - } - - if(super_root_is_header){ - NodeTraits::set_right(super_root, super_root_right_backup); - NodeTraits::set_parent(super_root, new_root); - } - else if(old_root_is_right){ - NodeTraits::set_right(super_root, new_root); - } - else{ - NodeTraits::set_right(super_root, super_root_right_backup); - NodeTraits::set_left(super_root, new_root); - } - if(plen) *plen = len; - return new_root; - } - - static node_ptr vine_to_subtree(const node_ptr & old_root, std::size_t count) - { - std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << floor_log2 (count + 1)); - std::size_t vine_nodes = count - leaf_nodes; - - node_ptr new_root = compress_subtree(old_root, leaf_nodes); - while(vine_nodes > 1){ - vine_nodes /= 2; - new_root = compress_subtree(new_root, vine_nodes); - } - return new_root; - } - - static node_ptr compress_subtree(const node_ptr & old_root, std::size_t count) - { - if(!old_root) return old_root; - - //To avoid irregularities in the algorithm (old_root can be - //left or right child or even the root of the tree) just put the - //root as the right child of its parent. First obtain - //information to restore the original relationship after - //the algorithm is applied. - node_ptr super_root = NodeTraits::get_parent(old_root); - BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root); - - //Get info - node_ptr super_root_right_backup = NodeTraits::get_right(super_root); - bool super_root_is_header = is_header(super_root); - bool old_root_is_right = is_right_child(old_root); - - //Put old_root as right child - NodeTraits::set_right(super_root, old_root); - - //Start the compression algorithm - node_ptr even_parent = super_root; - node_ptr new_root = old_root; - - while(count--){ - node_ptr even = NodeTraits::get_right(even_parent); - node_ptr odd = NodeTraits::get_right(even); - - if(new_root == old_root) - new_root = odd; - - node_ptr even_right = NodeTraits::get_left(odd); - NodeTraits::set_right(even, even_right); - if (even_right) - NodeTraits::set_parent(even_right, even); - - NodeTraits::set_right(even_parent, odd); - NodeTraits::set_parent(odd, even_parent); - NodeTraits::set_left(odd, even); - NodeTraits::set_parent(even, odd); - even_parent = odd; - } - - if(super_root_is_header){ - NodeTraits::set_parent(super_root, new_root); - NodeTraits::set_right(super_root, super_root_right_backup); - } - else if(old_root_is_right){ - NodeTraits::set_right(super_root, new_root); - } - else{ - NodeTraits::set_left(super_root, new_root); - NodeTraits::set_right(super_root, super_root_right_backup); - } - return new_root; - } - - //! Requires: "n" must be a node inserted in a tree. - //! - //! Effects: Returns a pointer to the header node of the tree. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - static node_ptr get_root(const node_ptr & node) - { - BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node))); - node_ptr x = NodeTraits::get_parent(node); - if(x){ - while(!is_header(x)){ - x = NodeTraits::get_parent(x); - } - return x; - } - else{ - return node; - } - } - - private: - template static node_ptr lower_bound_loop (node_ptr x, node_ptr y, const KeyType &key, KeyNodePtrCompare comp) @@ -1689,7 +1926,7 @@ class tree_algorithms } else{ // find z's successor - y = tree_algorithms::minimum (z_right); + y = bstree_algorithms::minimum (z_right); x = NodeTraits::get_right(y); // x might be null. } @@ -1707,23 +1944,23 @@ class tree_algorithms } else x_parent = y; - tree_algorithms::replace_own (z, y, header); + bstree_algorithms::replace_own (z, y, header); NodeTraits::set_parent(y, NodeTraits::get_parent(z)); } - else { // y == z --> z has only one child, or none + else { // y == z --> z has only one child, or void x_parent = NodeTraits::get_parent(z); if(x) NodeTraits::set_parent(x, x_parent); - tree_algorithms::replace_own (z, x, header); + bstree_algorithms::replace_own (z, x, header); if(NodeTraits::get_left(header) == z){ NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also NodeTraits::get_parent(z) : // makes leftmost == header if z == root - tree_algorithms::minimum (x)); + bstree_algorithms::minimum (x)); } if(NodeTraits::get_right(header) == z){ NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also NodeTraits::get_parent(z) : // makes rightmost == header if z == root - tree_algorithms::maximum(x)); + bstree_algorithms::maximum(x)); } } @@ -1733,10 +1970,19 @@ class tree_algorithms } }; -} //namespace detail { +/// @cond + +template +struct get_algo +{ + typedef bstree_algorithms type; +}; + +/// @endcond + } //namespace intrusive } //namespace boost #include -#endif //BOOST_INTRUSIVE_TREE_ALGORITHMS_HPP +#endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP diff --git a/cpp/BoostParts/boost/intrusive/circular_slist_algorithms.hpp b/cpp/BoostParts/boost/intrusive/circular_slist_algorithms.hpp index fc3848e8..fb5f75ab 100644 --- a/cpp/BoostParts/boost/intrusive/circular_slist_algorithms.hpp +++ b/cpp/BoostParts/boost/intrusive/circular_slist_algorithms.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace boost { @@ -396,6 +397,16 @@ class circular_slist_algorithms } }; +/// @cond + +template +struct get_algo +{ + typedef circular_slist_algorithms type; +}; + +/// @endcond + } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/detail/assert.hpp b/cpp/BoostParts/boost/intrusive/detail/assert.hpp index 33de97f7..3dacbcc3 100644 --- a/cpp/BoostParts/boost/intrusive/detail/assert.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/assert.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/clear_on_destructor_base.hpp b/cpp/BoostParts/boost/intrusive/detail/clear_on_destructor_base.hpp index 1b5c27ff..164fe409 100644 --- a/cpp/BoostParts/boost/intrusive/detail/clear_on_destructor_base.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/clear_on_destructor_base.hpp @@ -1,6 +1,6 @@ //////} // /////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-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) // @@ -17,7 +17,7 @@ namespace boost { namespace intrusive { namespace detail { -template +template class clear_on_destructor_base { protected: @@ -27,6 +27,10 @@ class clear_on_destructor_base } }; +template +class clear_on_destructor_base +{}; + } // namespace detail { } // namespace intrusive { } // namespace boost { diff --git a/cpp/BoostParts/boost/intrusive/detail/common_slist_algorithms.hpp b/cpp/BoostParts/boost/intrusive/detail/common_slist_algorithms.hpp index 166f78d4..a5433bb1 100644 --- a/cpp/BoostParts/boost/intrusive/detail/common_slist_algorithms.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/common_slist_algorithms.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/config_begin.hpp b/cpp/BoostParts/boost/intrusive/detail/config_begin.hpp index 7d153368..109a5908 100644 --- a/cpp/BoostParts/boost/intrusive/detail/config_begin.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/config_begin.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/config_end.hpp b/cpp/BoostParts/boost/intrusive/detail/config_end.hpp index d653030d..a081443e 100644 --- a/cpp/BoostParts/boost/intrusive/detail/config_end.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/config_end.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/ebo_functor_holder.hpp b/cpp/BoostParts/boost/intrusive/detail/ebo_functor_holder.hpp index 850d0743..3c2959b9 100644 --- a/cpp/BoostParts/boost/intrusive/detail/ebo_functor_holder.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/ebo_functor_holder.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Joaquin M Lopez Munoz 2006-2012 +// (C) Copyright Joaquin M Lopez Munoz 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/function_detector.hpp b/cpp/BoostParts/boost/intrusive/detail/function_detector.hpp index 08cee2d5..f8eccf9e 100644 --- a/cpp/BoostParts/boost/intrusive/detail/function_detector.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/function_detector.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. +// (C) Copyright Ion Gaztanaga 2009-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/generic_hook.hpp b/cpp/BoostParts/boost/intrusive/detail/generic_hook.hpp index 5ddd5207..8848aff9 100644 --- a/cpp/BoostParts/boost/intrusive/detail/generic_hook.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/generic_hook.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -24,85 +24,71 @@ namespace boost { namespace intrusive { -namespace detail { /// @cond -enum -{ NoBaseHook -, ListBaseHook -, SlistBaseHook -, SetBaseHook -, UsetBaseHook -, SplaySetBaseHook -, AvlSetBaseHook -, BsSetBaseHook -, AnyBaseHook +enum base_hook_type +{ NoBaseHookId +, ListBaseHookId +, SlistBaseHookId +, RbTreeBaseHookId +, HashBaseHookId +, SplayTreeBaseHookId +, AvlTreeBaseHookId +, BsTreeBaseHookId +, AnyBaseHookId }; -struct no_default_definer{}; -template -struct default_definer; +template +struct hook_tags_definer{}; -template -struct default_definer -{ typedef Hook default_list_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_list_hook; }; -template -struct default_definer -{ typedef Hook default_slist_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_slist_hook; }; -template -struct default_definer -{ typedef Hook default_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_rbtree_hook; }; -template -struct default_definer -{ typedef Hook default_uset_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_hashtable_hook; }; -template -struct default_definer -{ typedef Hook default_splay_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_splaytree_hook; }; -template -struct default_definer -{ typedef Hook default_avl_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_avltree_hook; }; -template -struct default_definer -{ typedef Hook default_bs_set_hook; }; +template +struct hook_tags_definer +{ typedef HookTags default_bstree_hook; }; -template -struct default_definer -{ typedef Hook default_any_hook; }; - -template -struct make_default_definer -{ - typedef typename detail::if_c - < BaseHookType != 0 - , default_definer - , no_default_definer>::type type; -}; +template +struct hook_tags_definer +{ typedef HookTags default_any_hook; }; template - < class GetNodeAlgorithms + < class NodeTraits , class Tag , link_mode_type LinkMode - , int HookType + , base_hook_type BaseHookType > -struct make_node_holder +struct hooktags_impl { - typedef typename detail::if_c - ::value - , detail::node_holder - < typename GetNodeAlgorithms::type::node - , Tag - , LinkMode - , HookType> - , typename GetNodeAlgorithms::type::node - >::type type; + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef NodeTraits node_traits; + static const bool is_base_hook = !detail::is_same::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const unsigned int type = BaseHookType; }; /// @endcond @@ -111,22 +97,28 @@ template < class GetNodeAlgorithms , class Tag , link_mode_type LinkMode - , int HookType + , base_hook_type BaseHookType > class generic_hook /// @cond - - //If the hook is a base hook, derive generic hook from detail::node_holder + //If the hook is a base hook, derive generic hook from node_holder //so that a unique base class is created to convert from the node - //to the type. This mechanism will be used by base_hook_traits. + //to the type. This mechanism will be used by bhtraits. // //If the hook is a member hook, generic hook will directly derive //from the hook. - : public make_default_definer - < generic_hook - , detail::is_same::value*HookType + : public detail::if_c + < detail::is_same::value + , typename GetNodeAlgorithms::type::node + , node_holder >::type - , public make_node_holder::type + //If this is the a default-tagged base hook derive from a class that + //will define an special internal typedef. Containers will be able to detect this + //special typedef and obtain generic_hook's internal types in order to deduce + //value_traits for this hook. + , public hook_tags_definer + < generic_hook + , detail::is_same::value*BaseHookType> /// @endcond { /// @cond @@ -136,16 +128,10 @@ class generic_hook typedef typename node_algorithms::const_node_ptr const_node_ptr; public: - struct boost_intrusive_tags - { - static const int hook_type = HookType; - static const link_mode_type link_mode = LinkMode; - typedef Tag tag; - typedef typename GetNodeAlgorithms::type::node_traits node_traits; - static const bool is_base_hook = !detail::is_same::value; - static const bool safemode_or_autounlink = - (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link; - }; + + typedef hooktags_impl + < typename GetNodeAlgorithms::type::node_traits + , Tag, LinkMode, BaseHookType> hooktags; node_ptr this_ptr() { return pointer_traits::pointer_to(static_cast(*this)); } @@ -158,14 +144,14 @@ class generic_hook generic_hook() { - if(boost_intrusive_tags::safemode_or_autounlink){ + if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } generic_hook(const generic_hook& ) { - if(boost_intrusive_tags::safemode_or_autounlink){ + if(hooktags::safemode_or_autounlink){ node_algorithms::init(this->this_ptr()); } } @@ -176,7 +162,7 @@ class generic_hook ~generic_hook() { destructor_impl - (*this, detail::link_dispatch()); + (*this, detail::link_dispatch()); } void swap_nodes(generic_hook &other) @@ -188,19 +174,18 @@ class generic_hook bool is_linked() const { //is_linked() can be only used in safe-mode or auto-unlink - BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink )); + BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink )); return !node_algorithms::unique(this->this_ptr()); } void unlink() { - BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink )); + BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); node_algorithms::unlink(this->this_ptr()); node_algorithms::init(this->this_ptr()); } }; -} //namespace detail } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/detail/has_member_function_callable_with.hpp b/cpp/BoostParts/boost/intrusive/detail/has_member_function_callable_with.hpp index 5651b4c1..be4a0153 100644 --- a/cpp/BoostParts/boost/intrusive/detail/has_member_function_callable_with.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-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) // diff --git a/cpp/BoostParts/boost/intrusive/detail/is_stateful_value_traits.hpp b/cpp/BoostParts/boost/intrusive/detail/is_stateful_value_traits.hpp index 8677c666..c98f6c6b 100644 --- a/cpp/BoostParts/boost/intrusive/detail/is_stateful_value_traits.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/is_stateful_value_traits.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. +// (C) Copyright Ion Gaztanaga 2009-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/detail/memory_util.hpp b/cpp/BoostParts/boost/intrusive/detail/memory_util.hpp index 7f69f91a..bfc9b149 100644 --- a/cpp/BoostParts/boost/intrusive/detail/memory_util.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/memory_util.hpp @@ -6,7 +6,7 @@ // ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-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) // @@ -45,6 +45,10 @@ template struct unvoid { typedef T type; }; template <> struct unvoid { struct type { }; }; template <> struct unvoid { struct type { }; }; +template struct unvoid_ref { typedef T &type; }; +template <> struct unvoid_ref { struct type_impl { }; typedef type_impl & type; }; +template <> struct unvoid_ref { struct type_impl { }; typedef type_impl & type; }; + template struct LowPriorityConversion { diff --git a/cpp/BoostParts/boost/intrusive/detail/mpl.hpp b/cpp/BoostParts/boost/intrusive/detail/mpl.hpp index a2d99734..6f99d7c7 100644 --- a/cpp/BoostParts/boost/intrusive/detail/mpl.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/mpl.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -283,20 +283,13 @@ struct alignment_of template struct is_same { - typedef char yes_type; - struct no_type - { - char padding[8]; - }; + static const bool value = false; +}; - template - static yes_type is_same_tester(V*, V*); - static no_type is_same_tester(...); - - static T *t; - static U *u; - - static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u)); +template +struct is_same +{ + static const bool value = true; }; template diff --git a/cpp/BoostParts/boost/intrusive/detail/parent_from_member.hpp b/cpp/BoostParts/boost/intrusive/detail/parent_from_member.hpp index f86a0e72..cf9f3794 100644 --- a/cpp/BoostParts/boost/intrusive/detail/parent_from_member.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/parent_from_member.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -30,18 +30,38 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t { //The implementation of a pointer to member is compiler dependent. #if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER) - //msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode) + + //MSVC compliant compilers use their the first 32 bits as offset (even in 64 bit mode) union caster_union { const Member Parent::* ptr_to_member; boost::int32_t offset; } caster; - caster.ptr_to_member = ptr_to_member; + //MSVC ABI can use up to 3 int32 to represent pointer to member data //with virtual base classes, in those cases there is no simple to - //obtain the address of parent. So static assert to avoid runtime errors + //obtain the address of the parent. So static assert to avoid runtime errors BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(boost::int32_t) ); + + caster.ptr_to_member = ptr_to_member; return std::ptrdiff_t(caster.offset); + //Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member + //types dereference seems to be: + // + // vboffset = [compile_time_offset if 2-int ptr2memb] / + // [ptr2memb.i32[2] if 3-int ptr2memb]. + // vbtable = *(this + vboffset); + // adj = vbtable[ptr2memb.i32[1]]; + // var = adj + (this + vboffset) + ptr2memb.i32[0]; + // + //To reverse the operation we need to + // - obtain vboffset (in 2-int ptr2memb implementation only) + // - Go to Parent's vbtable and obtain adjustment at index ptr2memb.i32[1] + // - parent = member - adj - vboffset - ptr2memb.i32[0] + // + //Even accessing to RTTI we might not be able to obtain this information + //so anyone who thinks it's possible, please send a patch. + //This works with gcc, msvc, ac++, ibmcpp #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \ defined(__IBMCPP__) || defined(__DECCXX) diff --git a/cpp/BoostParts/boost/intrusive/detail/preprocessor.hpp b/cpp/BoostParts/boost/intrusive/detail/preprocessor.hpp index 348b104b..b3ed6e68 100644 --- a/cpp/BoostParts/boost/intrusive/detail/preprocessor.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/preprocessor.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-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) // diff --git a/cpp/BoostParts/boost/intrusive/detail/rbtree_node.hpp b/cpp/BoostParts/boost/intrusive/detail/rbtree_node.hpp index 92d9417c..793d47fa 100644 --- a/cpp/BoostParts/boost/intrusive/detail/rbtree_node.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/rbtree_node.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012. +// (C) Copyright Ion Gaztanaga 2006-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -20,6 +20,8 @@ #include #include #include +#include +#include namespace boost { namespace intrusive { diff --git a/cpp/BoostParts/boost/intrusive/detail/slist_node.hpp b/cpp/BoostParts/boost/intrusive/detail/slist_node.hpp index ee929198..af124afb 100644 --- a/cpp/BoostParts/boost/intrusive/detail/slist_node.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/slist_node.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -15,7 +15,7 @@ #define BOOST_INTRUSIVE_SLIST_NODE_HPP #include -#include +#include #include #include @@ -54,41 +54,41 @@ struct slist_node_traits // slist_iterator provides some basic functions for a // node oriented bidirectional iterator: -template +template class slist_iterator - : public std::iterator - < std::forward_iterator_tag - , typename Container::value_type - , typename Container::difference_type - , typename detail::if_c::type - , typename detail::if_c::type - > + : public iiterator::iterator_base { protected: - typedef typename Container::real_value_traits real_value_traits; - typedef typename real_value_traits::node_traits node_traits; - typedef typename node_traits::node node; - typedef typename node_traits::node_ptr node_ptr; - typedef typename pointer_traits - ::template rebind_pointer ::type void_pointer; - static const bool store_container_ptr = - detail::store_cont_ptr_on_it::value; + typedef iiterator + types_t; + + static const bool stateful_value_traits = types_t::stateful_value_traits; + + typedef RealValueTraits real_value_traits; + typedef typename types_t::node_traits node_traits; + + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::void_pointer void_pointer; public: - typedef typename Container::value_type value_type; - typedef typename detail::if_c::type pointer; - typedef typename detail::if_c::type reference; + typedef typename types_t::value_type value_type; + typedef typename types_t::pointer pointer; + typedef typename types_t::reference reference; + + typedef typename pointer_traits + ::template rebind_pointer + ::type const_real_value_traits_ptr; slist_iterator() - : members_ (node_ptr(), 0) {} - explicit slist_iterator(const node_ptr & node, const Container *cont_ptr) - : members_ (node, cont_ptr) + explicit slist_iterator(const node_ptr & nodeptr, const const_real_value_traits_ptr &traits_ptr) + : members_(nodeptr, traits_ptr) {} - slist_iterator(slist_iterator const& other) - : members_(other.pointed_node(), other.get_container()) + slist_iterator(slist_iterator const& other) + : members_(other.pointed_node(), other.get_real_value_traits()) {} const node_ptr &pointed_node() const @@ -97,6 +97,9 @@ class slist_iterator slist_iterator &operator=(const node_ptr &node) { members_.nodeptr_ = node; return static_cast(*this); } + const_real_value_traits_ptr get_real_value_traits() const + { return pointer_traits::static_cast_from(members_.get_ptr()); } + public: slist_iterator& operator++() { @@ -123,39 +126,12 @@ class slist_iterator pointer operator->() const { return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); } - const Container *get_container() const - { - if(store_container_ptr) - return static_cast(members_.get_ptr()); - else - return 0; - } - - slist_iterator unconst() const - { return slist_iterator(this->pointed_node(), this->get_container()); } - - const real_value_traits *get_real_value_traits() const - { - if(store_container_ptr) - return &this->get_container()->get_real_value_traits(); - else - return 0; - } + slist_iterator unconst() const + { return slist_iterator(this->pointed_node(), this->get_real_value_traits()); } private: - struct members - : public detail::select_constptr - ::type - { - typedef typename detail::select_constptr - ::type Base; - members(const node_ptr &n_ptr, const void *cont) - : Base(cont), nodeptr_(n_ptr) - {} - - node_ptr nodeptr_; - } members_; + iiterator_members members_; }; } //namespace intrusive diff --git a/cpp/BoostParts/boost/intrusive/detail/tree_node.hpp b/cpp/BoostParts/boost/intrusive/detail/tree_node.hpp index aa3374e9..68891f1f 100644 --- a/cpp/BoostParts/boost/intrusive/detail/tree_node.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/tree_node.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -15,8 +15,11 @@ #include #include +#include +#include #include #include +#include namespace boost { namespace intrusive { @@ -77,43 +80,42 @@ struct tree_node_traits // tree_iterator provides some basic functions for a // node oriented bidirectional iterator: -template +template class tree_iterator - : public std::iterator - < std::bidirectional_iterator_tag - , typename Container::value_type - , typename Container::difference_type - , typename detail::if_c::type - , typename detail::if_c::type - > + : public iiterator::iterator_base { protected: - typedef typename Container::real_value_traits real_value_traits; - typedef typename Container::node_algorithms node_algorithms; - typedef typename real_value_traits::node_traits node_traits; - typedef typename node_traits::node node; - typedef typename node_traits::node_ptr node_ptr; - typedef typename pointer_traits::template - rebind_pointer::type void_pointer; - static const bool store_container_ptr = - detail::store_cont_ptr_on_it::value; + typedef iiterator< RealValueTraits, IsConst + , std::bidirectional_iterator_tag> types_t; + + typedef RealValueTraits real_value_traits; + typedef typename types_t::node_traits node_traits; + + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::void_pointer void_pointer; + static const bool stateful_value_traits = types_t::stateful_value_traits; + + typedef typename pointer_traits + ::template rebind_pointer + ::type const_real_value_traits_ptr; public: - typedef typename Container::value_type value_type; - typedef typename detail::if_c::type pointer; - typedef typename detail::if_c::type reference; + typedef typename types_t::value_type value_type; + typedef typename types_t::pointer pointer; + typedef typename types_t::reference reference; + typedef bstree_algorithms node_algorithms; tree_iterator() - : members_ (node_ptr(), (const void *)0) {} - explicit tree_iterator(const node_ptr & nodeptr, const Container *cont_ptr) - : members_ (nodeptr, cont_ptr) + explicit tree_iterator(const node_ptr & nodeptr, const const_real_value_traits_ptr &traits_ptr) + : members_(nodeptr, traits_ptr) {} - tree_iterator(tree_iterator const& other) - : members_(other.pointed_node(), other.get_container()) + tree_iterator(tree_iterator const& other) + : members_(other.pointed_node(), other.get_real_value_traits()) {} const node_ptr &pointed_node() const @@ -161,34 +163,21 @@ class tree_iterator pointer operator->() const { return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); } - const Container *get_container() const - { return static_cast(members_.get_ptr()); } - - const real_value_traits *get_real_value_traits() const - { return &this->get_container()->get_real_value_traits(); } + const_real_value_traits_ptr get_real_value_traits() const + { + return pointer_traits::static_cast_from(members_.get_ptr()); + } tree_iterator end_iterator_from_it() const { - return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_container()); + return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_real_value_traits()); } - tree_iterator unconst() const - { return tree_iterator(this->pointed_node(), this->get_container()); } + tree_iterator unconst() const + { return tree_iterator(this->pointed_node(), this->get_real_value_traits()); } private: - struct members - : public detail::select_constptr - ::type - { - typedef typename detail::select_constptr - ::type Base; - - members(const node_ptr &n_ptr, const void *cont) - : Base(cont), nodeptr_(n_ptr) - {} - - node_ptr nodeptr_; - } members_; + iiterator_members members_; }; } //namespace intrusive diff --git a/cpp/BoostParts/boost/intrusive/detail/utilities.hpp b/cpp/BoostParts/boost/intrusive/detail/utilities.hpp index bb342204..ab7b02c5 100644 --- a/cpp/BoostParts/boost/intrusive/detail/utilities.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/utilities.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -29,9 +29,36 @@ #include #include #include +#include +#include namespace boost { namespace intrusive { + +enum algo_types +{ + CircularListAlgorithms, + CircularSListAlgorithms, + LinearSListAlgorithms, + BsTreeAlgorithms, + RbTreeAlgorithms, + AvlTreeAlgorithms, + SgTreeAlgorithms, + SplayTreeAlgorithms, + TreapAlgorithms +}; + +template +struct get_algo; + +template +struct is_safe_autounlink +{ + static const bool value = + (int)link_mode == (int)auto_unlink || + (int)link_mode == (int)safe_link; +}; + namespace detail { template @@ -60,17 +87,12 @@ struct TRAITS_PREFIX##_bool_is_true\ };\ // -BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, boost_intrusive_tags::is_base_hook) +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook) BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook) BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_value_traits, external_value_traits) BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_bucket_traits, external_bucket_traits) BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(resizable, resizable) -template -struct node_holder - : public Node -{}; - template inline T* to_raw_pointer(T* p) { return p; } @@ -114,7 +136,7 @@ class init_disposer { NodeAlgorithms::init(p); } }; -template +template struct size_holder { static const bool constant_time_size = ConstantSize; @@ -166,17 +188,17 @@ struct size_holder {} }; -template +template struct key_nodeptr_comp : private detail::ebo_functor_holder { - typedef typename Container::real_value_traits real_value_traits; - typedef typename Container::value_type value_type; + typedef RealValueTraits real_value_traits; + typedef typename real_value_traits::value_type value_type; typedef typename real_value_traits::node_ptr node_ptr; typedef typename real_value_traits::const_node_ptr const_node_ptr; typedef detail::ebo_functor_holder base_t; - key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont) - : base_t(kcomp), cont_(cont) + key_nodeptr_comp(KeyValueCompare kcomp, const RealValueTraits *traits) + : base_t(kcomp), traits_(traits) {} template @@ -188,7 +210,7 @@ struct key_nodeptr_comp template const value_type & key_forward (const T &node, typename enable_if_c::value>::type * = 0) const - { return *cont_->get_real_value_traits().to_value_ptr(node); } + { return *traits_->to_value_ptr(node); } template const T & key_forward(const T &key, typename enable_if_c::value>::type* = 0) const @@ -199,27 +221,28 @@ struct key_nodeptr_comp bool operator()(const KeyType &key1, const KeyType2 &key2) const { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); } - const Container *cont_; + const RealValueTraits *traits_; }; -template +template struct node_cloner : private detail::ebo_functor_holder { - typedef typename Container::real_value_traits real_value_traits; - typedef typename Container::node_algorithms node_algorithms; - typedef typename real_value_traits::value_type value_type; - typedef typename real_value_traits::pointer pointer; - typedef typename real_value_traits::node_traits::node node; - typedef typename real_value_traits::node_ptr node_ptr; + typedef RealValueTraits real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node_ptr node_ptr; + typedef detail::ebo_functor_holder base_t; + typedef typename get_algo< AlgoType + , node_traits>::type node_algorithms; + static const bool safemode_or_autounlink = + is_safe_autounlink::value; + typedef typename real_value_traits::value_type value_type; + typedef typename real_value_traits::pointer pointer; + typedef typename node_traits::node node; typedef typename real_value_traits::const_node_ptr const_node_ptr; - typedef detail::ebo_functor_holder base_t; - enum { safemode_or_autounlink = - (int)real_value_traits::link_mode == (int)auto_unlink || - (int)real_value_traits::link_mode == (int)safe_link }; - node_cloner(F f, const Container *cont) - : base_t(f), cont_(cont) + node_cloner(F f, const RealValueTraits *traits) + : base_t(f), traits_(traits) {} node_ptr operator()(const node_ptr & p) @@ -228,50 +251,58 @@ struct node_cloner node_ptr operator()(const node &to_clone) { const value_type &v = - *cont_->get_real_value_traits().to_value_ptr + *traits_->to_value_ptr (pointer_traits::pointer_to(to_clone)); - node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v)); + node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); //Cloned node must be in default mode if the linking mode requires it if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); return n; } - const Container *cont_; + const RealValueTraits *traits_; }; -template +template struct node_disposer : private detail::ebo_functor_holder { - typedef typename Container::real_value_traits real_value_traits; - typedef typename real_value_traits::node_ptr node_ptr; + typedef RealValueTraits real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node_ptr node_ptr; typedef detail::ebo_functor_holder base_t; - typedef typename Container::node_algorithms node_algorithms; - enum { safemode_or_autounlink = - (int)real_value_traits::link_mode == (int)auto_unlink || - (int)real_value_traits::link_mode == (int)safe_link }; + typedef typename get_algo< AlgoType + , node_traits>::type node_algorithms; + static const bool safemode_or_autounlink = + is_safe_autounlink::value; - node_disposer(F f, const Container *cont) - : base_t(f), cont_(cont) + node_disposer(F f, const RealValueTraits *cont) + : base_t(f), traits_(cont) {} void operator()(const node_ptr & p) { if(safemode_or_autounlink) node_algorithms::init(p); - base_t::get()(cont_->get_real_value_traits().to_value_ptr(p)); + base_t::get()(traits_->to_value_ptr(p)); } - const Container *cont_; + const RealValueTraits *traits_; }; +template struct dummy_constptr { - dummy_constptr(const void *) + typedef typename boost::intrusive::pointer_traits:: + template rebind_pointer::type ConstVoidPtr; + + explicit dummy_constptr(ConstVoidPtr) {} - const void *get_ptr() const - { return 0; } + dummy_constptr() + {} + + ConstVoidPtr get_ptr() const + { return ConstVoidPtr(); } }; template @@ -280,7 +311,10 @@ struct constptr typedef typename boost::intrusive::pointer_traits:: template rebind_pointer::type ConstVoidPtr; - constptr(const void *ptr) + constptr() + {} + + explicit constptr(const ConstVoidPtr &ptr) : const_void_ptr_(ptr) {} @@ -296,7 +330,7 @@ struct select_constptr typedef typename detail::if_c < store_ptr , constptr - , dummy_constptr + , dummy_constptr >::type type; }; @@ -330,148 +364,6 @@ template void destructor_impl(Hook &, detail::link_dispatch) {} -template -struct base_hook_traits -{ - public: - typedef detail::node_holder - node_holder; - typedef typename NodeTraits::node node; - typedef NodeTraits node_traits; - typedef T value_type; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; - typedef typename pointer_traits:: - template rebind_pointer::type pointer; - typedef typename pointer_traits:: - template rebind_pointer::type const_pointer; - //typedef typename pointer_traits::reference reference; - //typedef typename pointer_traits::reference const_reference; - typedef T & reference; - typedef const T & const_reference; - typedef node_holder & node_holder_reference; - typedef const node_holder & const_node_holder_reference; - typedef node& node_reference; - typedef const node & const_node_reference; - - static const link_mode_type link_mode = LinkMode; - - static pointer to_value_ptr(const node_ptr & n) - { - return pointer_traits::pointer_to - (static_cast(static_cast(*n))); - } - - static const_pointer to_value_ptr(const const_node_ptr & n) - { - return pointer_traits::pointer_to - (static_cast(static_cast(*n))); - } - - static node_ptr to_node_ptr(reference value) - { - return pointer_traits::pointer_to - (static_cast(static_cast(value))); - } - - static const_node_ptr to_node_ptr(const_reference value) - { - return pointer_traits::pointer_to - (static_cast(static_cast(value))); - } -}; - -template -struct member_hook_traits -{ - public: - typedef Hook hook_type; - typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; - typedef typename node_traits::node node; - typedef T value_type; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; - typedef typename pointer_traits:: - template rebind_pointer::type pointer; - typedef typename pointer_traits:: - template rebind_pointer::type const_pointer; - typedef T & reference; - typedef const T & const_reference; - typedef node& node_reference; - typedef const node & const_node_reference; - typedef hook_type& hook_reference; - typedef const hook_type & const_hook_reference; - - static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode; - - static node_ptr to_node_ptr(reference value) - { - return pointer_traits::pointer_to - (static_cast(static_cast(value.*P))); - } - - static const_node_ptr to_node_ptr(const_reference value) - { - return pointer_traits::pointer_to - (static_cast(static_cast(value.*P))); - } - - static pointer to_value_ptr(const node_ptr & n) - { - return pointer_traits::pointer_to - (*detail::parent_from_member - (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); - } - - static const_pointer to_value_ptr(const const_node_ptr & n) - { - return pointer_traits::pointer_to - (*detail::parent_from_member - (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); - } -}; - -template -struct function_hook_traits -{ - public: - typedef typename Functor::hook_type hook_type; - typedef typename Functor::hook_ptr hook_ptr; - typedef typename Functor::const_hook_ptr const_hook_ptr; - typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; - typedef typename node_traits::node node; - typedef typename Functor::value_type value_type; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; - typedef typename pointer_traits:: - template rebind_pointer::type pointer; - typedef typename pointer_traits:: - template rebind_pointer::type const_pointer; - typedef value_type & reference; - typedef const value_type & const_reference; - static const link_mode_type link_mode = hook_type::boost_intrusive_tags::link_mode; - - static node_ptr to_node_ptr(reference value) - { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } - - static const_node_ptr to_node_ptr(const_reference value) - { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } - - static pointer to_value_ptr(const node_ptr & n) - { return Functor::to_value_ptr(to_hook_ptr(n)); } - - static const_pointer to_value_ptr(const const_node_ptr & n) - { return Functor::to_value_ptr(to_hook_ptr(n)); } - - private: - static hook_ptr to_hook_ptr(const node_ptr & n) - { return hook_ptr(&*static_cast(&*n)); } - - static const_hook_ptr to_hook_ptr(const const_node_ptr & n) - { return const_hook_ptr(&*static_cast(&*n)); } -}; - - //This function uses binary search to discover the //highest set bit of the integer inline std::size_t floor_log2 (std::size_t x) @@ -492,6 +384,8 @@ inline std::size_t floor_log2 (std::size_t x) return log2; } +//Thanks to Laurent de Soras in +//http://www.flipcode.com/archives/Fast_log_Function.shtml inline float fast_log2 (float val) { union caster_t @@ -502,13 +396,15 @@ inline float fast_log2 (float val) caster.val = val; boost::uint32_t x = caster.x; - const int log_2 = (int)(((x >> 23) & 255) - 128); - x &= ~(255 << 23); - x += 127 << 23; + const int log_2 = int((x >> 23) & 255) - 128; + x &= ~(boost::uint32_t(255u) << 23u); + x += boost::uint32_t(127) << 23u; caster.x = x; val = caster.val; + //1+log2(m), m ranging from 1 to 2 + //3rd degree polynomial keeping first derivate continuity. + //For less precision the line can be commented out val = ((-1.0f/3.f) * val + 2.f) * val - (2.0f/3.f); - return (val + log_2); } @@ -533,6 +429,8 @@ struct sqrt2_pow_max >::t static const std::size_t pow = 31; }; +#ifndef BOOST_NO_INT64_T + template struct sqrt2_pow_max >::type> { @@ -540,6 +438,8 @@ struct sqrt2_pow_max >::t static const std::size_t pow = 63; }; +#endif //BOOST_NO_INT64_T + // Returns floor(pow(sqrt(2), x * 2 + 1)). // Defined for X from 0 up to the number of bits in size_t minus 1. inline std::size_t sqrt2_pow_2xplus1 (std::size_t x) @@ -605,72 +505,47 @@ class exception_array_disposer } }; -template -struct store_cont_ptr_on_it_impl -{ - static const bool value = is_stateful_value_traits::value; -}; - -template -struct store_cont_ptr_on_it_impl -{ - static const bool value = true; -}; - -template -struct store_cont_ptr_on_it -{ - typedef typename Container::value_traits value_traits; - static const bool value = store_cont_ptr_on_it_impl - ::value>::value; -}; - -template +template struct node_to_value : public detail::select_constptr < typename pointer_traits - ::template rebind_pointer::type - , detail::store_cont_ptr_on_it::value + ::template rebind_pointer::type + , is_stateful_value_traits::value >::type { - static const bool store_container_ptr = - detail::store_cont_ptr_on_it::value; - - typedef typename Container::real_value_traits real_value_traits; - typedef typename real_value_traits::value_type value_type; + static const bool stateful_value_traits = is_stateful_value_traits::value; typedef typename detail::select_constptr < typename pointer_traits - ::template rebind_pointer::type - , store_container_ptr >::type Base; - typedef typename real_value_traits::node_traits::node node; - typedef typename detail::add_const_if_c - ::type vtype; - typedef typename detail::add_const_if_c - ::type ntype; - typedef typename pointer_traits - ::template rebind_pointer::type npointer; + :: + template rebind_pointer::type + , stateful_value_traits >::type Base; - node_to_value(const Container *cont) - : Base(cont) + typedef RealValueTraits real_value_traits; + typedef typename real_value_traits::value_type value_type; + typedef typename real_value_traits::node_traits::node node; + typedef typename detail::add_const_if_c + ::type vtype; + typedef typename detail::add_const_if_c + ::type ntype; + typedef typename pointer_traits + :: + template rebind_pointer::type npointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_real_value_traits_ptr; + + node_to_value(const const_real_value_traits_ptr &ptr) + : Base(ptr) {} typedef vtype & result_type; typedef ntype & first_argument_type; - const Container *get_container() const + const_real_value_traits_ptr get_real_value_traits() const { - if(store_container_ptr) - return static_cast(Base::get_ptr()); + if(stateful_value_traits) + return pointer_traits::static_cast_from(Base::get_ptr()); else - return 0; - } - - const real_value_traits *get_real_value_traits() const - { - if(store_container_ptr) - return &this->get_container()->get_real_value_traits(); - else - return 0; + return const_real_value_traits_ptr(); } result_type operator()(first_argument_type arg) const @@ -849,7 +724,346 @@ class reverse_iterator It m_current; // the wrapped iterator }; +template +struct uncast_types +{ + typedef typename pointer_traits::element_type element_type; + typedef typename remove_const::type non_const_type; + typedef typename pointer_traits:: + template rebind_pointer::type non_const_pointer; + typedef pointer_traits non_const_traits; +}; + +template +static typename uncast_types::non_const_pointer + uncast(const ConstNodePtr & ptr) +{ + return uncast_types::non_const_traits::const_cast_from(ptr); +} + } //namespace detail + +template +struct node_holder + : public Node +{}; + +template +struct bhtraits_base +{ + public: + typedef NodePtr node_ptr; + typedef typename pointer_traits::element_type node; + typedef node_holder node_holder_type; + typedef T value_type; + typedef typename pointer_traits:: + template rebind_pointer::type const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + //typedef typename pointer_traits::reference reference; + //typedef typename pointer_traits::reference const_reference; + typedef T & reference; + typedef const T & const_reference; + typedef node_holder_type & node_holder_reference; + typedef const node_holder_type & const_node_holder_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + + static pointer to_value_ptr(const node_ptr & n) + { + return pointer_traits::pointer_to + (static_cast(static_cast(*n))); + } + + static const_pointer to_value_ptr(const const_node_ptr & n) + { + return pointer_traits::pointer_to + (static_cast(static_cast(*n))); + } + + static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value))); + } + + static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value))); + } +}; + +template +struct bhtraits + : public bhtraits_base +{ + static const link_mode_type link_mode = LinkMode; + typedef NodeTraits node_traits; +}; + +/* +template::element_type T::* P> +struct mhtraits_base +{ + public: + typedef typename pointer_traits::element_type node; + typedef T value_type; + typedef NodePtr node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + + static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to + (static_cast(value.*P)); + } + + static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to + (static_cast(value.*P)); + } + + static pointer to_value_ptr(const node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (boost::intrusive::detail::to_raw_pointer(n), P)); + } + + static const_pointer to_value_ptr(const const_node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (boost::intrusive::detail::to_raw_pointer(n), P)); + } +}; + + +template +struct mhtraits + : public mhtraits_base +{ + static const link_mode_type link_mode = LinkMode; + typedef NodeTraits node_traits; +}; +*/ + + +template +struct mhtraits +{ + public: + typedef Hook hook_type; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef T value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + typedef hook_type& hook_reference; + typedef const hook_type & const_hook_reference; + + static const link_mode_type link_mode = Hook::hooktags::link_mode; + + static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + static pointer to_value_ptr(const node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); + } + + static const_pointer to_value_ptr(const const_node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::intrusive::detail::to_raw_pointer(n)), P)); + } +}; + + +template +struct fhtraits +{ + public: + typedef typename Functor::hook_type hook_type; + typedef typename Functor::hook_ptr hook_ptr; + typedef typename Functor::const_hook_ptr const_hook_ptr; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename Functor::value_type value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef value_type & reference; + typedef const value_type & const_reference; + static const link_mode_type link_mode = hook_type::hooktags::link_mode; + + static node_ptr to_node_ptr(reference value) + { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } + + static const_node_ptr to_node_ptr(const_reference value) + { return static_cast(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); } + + static pointer to_value_ptr(const node_ptr & n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + static const_pointer to_value_ptr(const const_node_ptr & n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + private: + static hook_ptr to_hook_ptr(const node_ptr & n) + { return hook_ptr(&*static_cast(&*n)); } + + static const_hook_ptr to_hook_ptr(const const_node_ptr & n) + { return const_hook_ptr(&*static_cast(&*n)); } +}; + +template +struct iiterator +{ + typedef RealValueTraits real_value_traits; + typedef typename real_value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef ::boost::intrusive::pointer_traits nodepointer_traits_t; + typedef typename nodepointer_traits_t::template + rebind_pointer::type void_pointer; + typedef typename RealValueTraits::value_type value_type; + typedef typename RealValueTraits::pointer nonconst_pointer; + typedef typename RealValueTraits::const_pointer yesconst_pointer; + typedef typename ::boost::intrusive::pointer_traits + ::reference nonconst_reference; + typedef typename ::boost::intrusive::pointer_traits + ::reference yesconst_reference; + typedef typename nodepointer_traits_t::difference_type difference_type; + typedef typename detail::if_c + ::type pointer; + typedef typename detail::if_c + ::type reference; + typedef std::iterator + < Category + , value_type + , difference_type + , pointer + , reference + > iterator_base; + static const bool stateful_value_traits = + detail::is_stateful_value_traits::value; +}; + +template +struct iiterator_members +{ + typedef ::boost::intrusive::pointer_traits pointer_traits_t; + typedef typename pointer_traits_t::template + rebind_pointer::type const_void_pointer; + + iiterator_members() + {} + + iiterator_members(const NodePtr &n_ptr, const const_void_pointer &data) + : nodeptr_(n_ptr), ptr_(data) + {} + + const_void_pointer get_ptr() const + { return ptr_; } + + NodePtr nodeptr_; + const_void_pointer ptr_; +}; + +template +struct iiterator_members +{ + typedef ::boost::intrusive::pointer_traits pointer_traits_t; + typedef typename pointer_traits_t::template + rebind_pointer::type const_void_pointer; + + iiterator_members() + {} + + iiterator_members(const NodePtr &n_ptr, const const_void_pointer &) + : nodeptr_(n_ptr) + {} + + const_void_pointer get_ptr() const + { return const_void_pointer(); } + + NodePtr nodeptr_; +}; + +template +struct get_less +{ + typedef Less type; +}; + +template +struct get_less +{ + typedef ::std::less type; +}; + +template +struct get_equal_to +{ + typedef EqualTo type; +}; + +template +struct get_equal_to +{ + typedef ::std::equal_to type; +}; + +template +struct get_hash +{ + typedef Hash type; +}; + +template +struct get_hash +{ + typedef ::boost::hash type; +}; + +struct empty{}; + } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/detail/workaround.hpp b/cpp/BoostParts/boost/intrusive/detail/workaround.hpp index 123fb9fb..71a50c86 100644 --- a/cpp/BoostParts/boost/intrusive/detail/workaround.hpp +++ b/cpp/BoostParts/boost/intrusive/detail/workaround.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-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) // @@ -17,6 +17,10 @@ #define BOOST_INTRUSIVE_PERFECT_FORWARDING #endif +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE +#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE + #include #endif //#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP diff --git a/cpp/BoostParts/boost/intrusive/intrusive_fwd.hpp b/cpp/BoostParts/boost/intrusive/intrusive_fwd.hpp index c95767ef..0e5e21c1 100644 --- a/cpp/BoostParts/boost/intrusive/intrusive_fwd.hpp +++ b/cpp/BoostParts/boost/intrusive/intrusive_fwd.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -19,15 +19,6 @@ /// @cond -namespace boost { - -namespace intrusive { - -struct none; - -} //namespace intrusive{ -} //namespace boost{ - namespace boost { namespace intrusive { @@ -53,11 +44,11 @@ class rbtree_algorithms; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none - , class O5 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void > #else template @@ -66,9 +57,9 @@ class slist; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -77,9 +68,9 @@ class slist_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -90,9 +81,9 @@ class slist_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none + , class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -101,9 +92,9 @@ class list; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -112,9 +103,9 @@ class list_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -123,9 +114,9 @@ class list_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -136,10 +127,10 @@ class list_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -149,10 +140,10 @@ class rbtree; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -162,10 +153,10 @@ class set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -174,10 +165,10 @@ class multiset; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -186,10 +177,10 @@ class set_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -200,10 +191,10 @@ class set_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -213,10 +204,10 @@ class splaytree; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -226,10 +217,10 @@ class splay_set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -238,9 +229,9 @@ class splay_multiset; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -249,9 +240,9 @@ class splay_set_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -262,10 +253,10 @@ class splay_set_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -275,10 +266,10 @@ class avltree; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -288,10 +279,10 @@ class avl_set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -300,10 +291,10 @@ class avl_multiset; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -312,10 +303,10 @@ class avl_set_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -327,10 +318,10 @@ class avl_set_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -340,10 +331,10 @@ class treap; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -353,10 +344,10 @@ class treap_set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -371,10 +362,10 @@ struct priority_compare; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -384,10 +375,10 @@ class sgtree; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -397,10 +388,10 @@ class sg_set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -409,9 +400,48 @@ class sg_multiset; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class bstree; + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class bs_set; + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class bs_multiset; + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -420,9 +450,9 @@ class bs_set_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -434,16 +464,16 @@ class bs_set_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none - , class O5 = none - , class O6 = none - , class O7 = none - , class O8 = none - , class O9 = none - , class O10 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void > #else template @@ -453,16 +483,16 @@ class hashtable; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none - , class O5 = none - , class O6 = none - , class O7 = none - , class O8 = none - , class O9 = none - , class O10 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void > #else template @@ -472,16 +502,16 @@ class unordered_set; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none - , class O5 = none - , class O6 = none - , class O7 = none - , class O8 = none - , class O9 = none - , class O10 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void > #else template @@ -490,10 +520,10 @@ class unordered_multiset; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -502,10 +532,10 @@ class unordered_set_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void > #else template @@ -514,9 +544,9 @@ class unordered_set_member_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template @@ -525,9 +555,9 @@ class any_base_hook; #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template - < class O1 = none - , class O2 = none - , class O3 = none + < class O1 = void + , class O2 = void + , class O3 = void > #else template diff --git a/cpp/BoostParts/boost/intrusive/linear_slist_algorithms.hpp b/cpp/BoostParts/boost/intrusive/linear_slist_algorithms.hpp index db4092d2..86f9bb32 100644 --- a/cpp/BoostParts/boost/intrusive/linear_slist_algorithms.hpp +++ b/cpp/BoostParts/boost/intrusive/linear_slist_algorithms.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -319,6 +320,16 @@ class linear_slist_algorithms } }; +/// @cond + +template +struct get_algo +{ + typedef linear_slist_algorithms type; +}; + +/// @endcond + } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/link_mode.hpp b/cpp/BoostParts/boost/intrusive/link_mode.hpp index c04f7752..73d30446 100644 --- a/cpp/BoostParts/boost/intrusive/link_mode.hpp +++ b/cpp/BoostParts/boost/intrusive/link_mode.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/options.hpp b/cpp/BoostParts/boost/intrusive/options.hpp index 5449a44c..6d06a79e 100644 --- a/cpp/BoostParts/boost/intrusive/options.hpp +++ b/cpp/BoostParts/boost/intrusive/options.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -26,6 +26,7 @@ namespace intrusive { /// @cond +//typedef void default_tag; struct default_tag; struct member_tag; @@ -45,11 +46,13 @@ struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\ BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_list_hook); BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_slist_hook); -BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_set_hook); -BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_uset_hook); -BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avl_set_hook); -BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splay_set_hook); -BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bs_set_hook); +BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_rbtree_hook); +BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook); +BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook); +BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook); +//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splaytree_hook); +//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_sgtree_hook); +//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_treap_hook); #undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION @@ -61,6 +64,15 @@ struct eval_value_traits typedef typename ValueTraits::value_traits type; }; +template +struct get_real_value_traits + : public eval_if_c + < external_value_traits_bool_is_true::value + , eval_value_traits + , identity + > +{}; + template struct eval_bucket_traits { @@ -70,29 +82,36 @@ struct eval_bucket_traits template struct concrete_hook_base_value_traits { - typedef typename BaseHook::boost_intrusive_tags tags; - typedef detail::base_hook_traits + typedef typename BaseHook::hooktags tags; + typedef bhtraits < T , typename tags::node_traits , tags::link_mode , typename tags::tag - , tags::hook_type> type; + , tags::type> type; }; template struct concrete_hook_base_node_traits -{ typedef typename BaseHook::boost_intrusive_tags::node_traits type; }; +{ typedef typename BaseHook::hooktags::node_traits type; }; -template +template struct any_hook_base_value_traits { - typedef typename BaseHook::boost_intrusive_tags tags; - typedef detail::base_hook_traits + //AnyToSomeHook value_traits derive from a generic_hook + //The generic_hook is configured with any_node_traits + //and AnyToSomeHook::value_traits with the correct + //node traits for the container, so use node_traits + //from AnyToSomeHook_ProtoValueTraits and the rest of + //elements from the hooktags member of the generic_hook + typedef AnyToSomeHook_ProtoValueTraits proto_value_traits; + typedef bhtraits < T - , typename BaseHook::node_traits - , tags::link_mode - , typename tags::tag - , tags::hook_type> type; + , typename proto_value_traits::node_traits + , proto_value_traits::hooktags::link_mode + , typename proto_value_traits::hooktags::tag + , proto_value_traits::hooktags::type + > type; }; template @@ -139,6 +158,7 @@ struct get_value_traits ,detail::apply ,detail::identity >::type supposed_value_traits; + //...if it's a default hook typedef typename detail::eval_if_c < internal_base_hook_bool_is_true::value @@ -183,16 +203,6 @@ struct get_node_traits } //namespace detail{ - -//!This type indicates that no option is being used -//!and that the default options should be used -struct none -{ - template - struct pack : Base - { }; -}; - /// @endcond //!This option setter specifies if the intrusive @@ -314,7 +324,7 @@ struct value_traits template struct pack : Base { - typedef ValueTraits value_traits; + typedef ValueTraits proto_value_traits; }; /// @endcond }; @@ -327,7 +337,22 @@ template< typename Parent struct member_hook { /// @cond - typedef detail::member_hook_traits +/* + typedef typename MemberHook::hooktags::node_traits node_traits; + typedef typename node_traits::node node_type; + typedef node_type Parent::* Ptr2MemNode; + typedef mhtraits + < Parent + , node_traits + //This cast is really ugly but necessary to reduce template bloat. + //Since we control the layout between the hook and the node, and there is + //always single inheritance, the offset of the node is exactly the offset of + //the hook. Since the node type is shared between all member hooks, this saves + //quite a lot of symbol stuff. + , (Ptr2MemNode)PtrToMember + , MemberHook::hooktags::link_mode> member_value_traits; +*/ + typedef mhtraits < Parent , MemberHook , PtrToMember @@ -335,7 +360,7 @@ struct member_hook template struct pack : Base { - typedef member_value_traits value_traits; + typedef member_value_traits proto_value_traits; }; /// @endcond }; @@ -348,12 +373,12 @@ template< typename Functor> struct function_hook { /// @cond - typedef detail::function_hook_traits + typedef fhtraits function_value_traits; template struct pack : Base { - typedef function_value_traits value_traits; + typedef function_value_traits proto_value_traits; }; /// @endcond }; @@ -368,7 +393,7 @@ struct base_hook template struct pack : Base { - typedef BaseHook value_traits; + typedef BaseHook proto_value_traits; }; /// @endcond }; @@ -583,6 +608,13 @@ struct incremental /// @cond +struct none +{ + template + struct pack : Base + {}; +}; + //To-do: pass to variadic templates #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) @@ -594,25 +626,25 @@ struct do_pack }; template -struct do_pack +struct do_pack { - //Avoid packing "none" to shorten template names + //Avoid packing "void" to shorten template names typedef Prev type; }; template < class DefaultOptions - , class O1 = none - , class O2 = none - , class O3 = none - , class O4 = none - , class O5 = none - , class O6 = none - , class O7 = none - , class O8 = none - , class O9 = none - , class O10 = none - , class O11 = none + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void > struct pack_options { @@ -788,17 +820,15 @@ struct pack_options #endif struct hook_defaults - : public pack_options - < none - , void_pointer - , link_mode - , tag - , optimize_size - , store_hash - , linear - , optimize_multikey - >::type -{}; +{ + typedef void* void_pointer; + static const link_mode_type link_mode = safe_link; + typedef default_tag tag; + static const bool optimize_size = false; + static const bool store_hash = false; + static const bool linear = false; + static const bool optimize_multikey = false; +}; /// @endcond diff --git a/cpp/BoostParts/boost/intrusive/pointer_plus_bits.hpp b/cpp/BoostParts/boost/intrusive/pointer_plus_bits.hpp index 273452c7..7b0a793e 100644 --- a/cpp/BoostParts/boost/intrusive/pointer_plus_bits.hpp +++ b/cpp/BoostParts/boost/intrusive/pointer_plus_bits.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2012 +// (C) Copyright Ion Gaztanaga 2007-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/cpp/BoostParts/boost/intrusive/pointer_traits.hpp b/cpp/BoostParts/boost/intrusive/pointer_traits.hpp index a19ee6d9..21b14a19 100644 --- a/cpp/BoostParts/boost/intrusive/pointer_traits.hpp +++ b/cpp/BoostParts/boost/intrusive/pointer_traits.hpp @@ -6,7 +6,7 @@ // ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-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) // @@ -74,7 +74,7 @@ struct pointer_traits typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT (boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type; // - typedef typename boost::intrusive::detail::unvoid::type& reference; + typedef typename boost::intrusive::detail::unvoid_ref::type reference; // template struct rebind_pointer { @@ -224,7 +224,7 @@ struct pointer_traits //!shall be used instead of rebind to obtain a pointer to U. template using rebind = U*; #else - typedef typename boost::intrusive::detail::unvoid::type& reference; + typedef typename boost::intrusive::detail::unvoid_ref::type reference; #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template using rebind = U*; #endif diff --git a/cpp/BoostParts/boost/intrusive/rbtree.hpp b/cpp/BoostParts/boost/intrusive/rbtree.hpp index 32e6b9e1..8acfe450 100644 --- a/cpp/BoostParts/boost/intrusive/rbtree.hpp +++ b/cpp/BoostParts/boost/intrusive/rbtree.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -13,10 +13,8 @@ #define BOOST_INTRUSIVE_RBTREE_HPP #include -#include #include #include -#include #include #include @@ -24,11 +22,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -41,26 +39,14 @@ namespace intrusive { /// @cond -template -struct setopt +struct rbtree_defaults { - typedef ValueTraits value_traits; - typedef Compare compare; - typedef SizeType size_type; - static const bool constant_time_size = ConstantTimeSize; + typedef detail::default_rbtree_hook proto_value_traits; + static const bool constant_time_size = true; + typedef std::size_t size_type; + typedef void compare; }; -template -struct set_defaults - : pack_options - < none - , base_hook - , constant_time_size - , size_type - , compare > - >::type -{}; - /// @endcond //! The class template rbtree is an intrusive red-black tree container, that @@ -79,1633 +65,395 @@ struct set_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class rbtree_impl - : private detail::clear_on_destructor_base > -{ - template friend class detail::clear_on_destructor_base; - public: - typedef typename Config::value_traits value_traits; /// @cond - static const bool external_value_traits = - detail::external_value_traits_bool_is_true::value; - typedef typename detail::eval_if_c - < external_value_traits - , detail::eval_value_traits - , detail::identity - >::type real_value_traits; + : public bstree_impl + /// @endcond +{ + public: + typedef ValueTraits value_traits; + /// @cond + typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType + , ConstantTimeSize, RbTreeAlgorithms> tree_type; + typedef tree_type implementation_defined; /// @endcond - typedef typename real_value_traits::pointer pointer; - typedef typename real_value_traits::const_pointer const_pointer; - typedef typename pointer_traits::element_type value_type; - typedef value_type key_type; - typedef typename pointer_traits::reference reference; - typedef typename pointer_traits::reference const_reference; - typedef typename pointer_traits::difference_type difference_type; - typedef typename Config::size_type size_type; - typedef typename Config::compare value_compare; - typedef value_compare key_compare; - typedef tree_iterator iterator; - typedef tree_iterator const_iterator; - typedef boost::intrusive::detail::reverse_iterator reverse_iterator; - typedef boost::intrusive::detail::reverse_iteratorconst_reverse_iterator; - typedef typename real_value_traits::node_traits node_traits; - typedef typename node_traits::node node; - typedef typename node_traits::node_ptr node_ptr; - typedef typename node_traits::const_node_ptr const_node_ptr; - typedef rbtree_algorithms node_algorithms; + typedef typename implementation_defined::pointer pointer; + typedef typename implementation_defined::const_pointer const_pointer; + typedef typename implementation_defined::value_type value_type; + typedef typename implementation_defined::key_type key_type; + typedef typename implementation_defined::reference reference; + typedef typename implementation_defined::const_reference const_reference; + typedef typename implementation_defined::difference_type difference_type; + typedef typename implementation_defined::size_type size_type; + typedef typename implementation_defined::value_compare value_compare; + typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::iterator iterator; + typedef typename implementation_defined::const_iterator const_iterator; + typedef typename implementation_defined::reverse_iterator reverse_iterator; + typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator; + typedef typename implementation_defined::node_traits node_traits; + typedef typename implementation_defined::node node; + typedef typename implementation_defined::node_ptr node_ptr; + typedef typename implementation_defined::const_node_ptr const_node_ptr; + typedef typename implementation_defined::node_algorithms node_algorithms; - static const bool constant_time_size = Config::constant_time_size; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool constant_time_size = implementation_defined::constant_time_size; /// @cond private: - typedef detail::size_holder size_traits; //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree_impl) - enum { safemode_or_autounlink = - (int)real_value_traits::link_mode == (int)auto_unlink || - (int)real_value_traits::link_mode == (int)safe_link }; - - //Constant-time size is incompatible with auto-unlink hooks! - BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); - - struct header_plus_size : public size_traits - { node header_; }; - - struct node_plus_pred_t : public detail::ebo_functor_holder - { - node_plus_pred_t(const value_compare &comp) - : detail::ebo_functor_holder(comp) - {} - header_plus_size header_plus_size_; - }; - - struct data_t : public rbtree_impl::value_traits - { - typedef typename rbtree_impl::value_traits value_traits; - data_t(const value_compare & comp, const value_traits &val_traits) - : value_traits(val_traits), node_plus_pred_(comp) - {} - node_plus_pred_t node_plus_pred_; - } data_; - - const value_compare &priv_comp() const - { return data_.node_plus_pred_.get(); } - - value_compare &priv_comp() - { return data_.node_plus_pred_.get(); } - - const value_traits &priv_value_traits() const - { return data_; } - - value_traits &priv_value_traits() - { return data_; } - - node_ptr priv_header_ptr() - { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } - - const_node_ptr priv_header_ptr() const - { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } - - static node_ptr uncast(const const_node_ptr & ptr) - { return pointer_traits::const_cast_from(ptr); } - - size_traits &priv_size_traits() - { return data_.node_plus_pred_.header_plus_size_; } - - const size_traits &priv_size_traits() const - { return data_.node_plus_pred_.header_plus_size_; } - - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_; } - - const real_value_traits &get_real_value_traits(detail::bool_) const - { return data_.get_value_traits(*this); } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_; } - - real_value_traits &get_real_value_traits(detail::bool_) - { return data_.get_value_traits(*this); } - - protected: - value_compare &prot_comp() - { return priv_comp(); } - - const node &prot_header_node() const - { return data_.node_plus_pred_.header_plus_size_.header_; } - - node &prot_header_node() - { return data_.node_plus_pred_.header_plus_size_.header_; } - - void prot_set_size(size_type s) - { this->priv_size_traits().set_size(s); } - /// @endcond public: - const real_value_traits &get_real_value_traits() const - { return this->get_real_value_traits(detail::bool_()); } + typedef typename implementation_defined::insert_commit_data insert_commit_data; - real_value_traits &get_real_value_traits() - { return this->get_real_value_traits(detail::bool_()); } - - typedef typename node_algorithms::insert_commit_data insert_commit_data; - - //! Effects: Constructs an empty tree. - //! - //! Complexity: Constant. - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructorof the value_compare object throws. Basic guarantee. + //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &) explicit rbtree_impl( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : data_(cmp, v_traits) - { - node_algorithms::init_header(this->priv_header_ptr()); - this->priv_size_traits().set_size(size_type(0)); - } + : tree_type(cmp, v_traits) + {} - //! Requires: Dereferencing iterator must yield an lvalue of type value_type. - //! cmp must be a comparison function that induces a strict weak ordering. - //! - //! Effects: Constructs an empty tree and inserts elements from - //! [b, e). - //! - //! Complexity: Linear in N if [b, e) is already sorted using - //! comp and otherwise N * log N, where N is the distance between first and last. - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee. + //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &) template rbtree_impl( bool unique, Iterator b, Iterator e , const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : data_(cmp, v_traits) - { - node_algorithms::init_header(this->priv_header_ptr()); - this->priv_size_traits().set_size(size_type(0)); - if(unique) - this->insert_unique(b, e); - else - this->insert_equal(b, e); - } - - //! Effects: to-do - //! - rbtree_impl(BOOST_RV_REF(rbtree_impl) x) - : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) - { - node_algorithms::init_header(this->priv_header_ptr()); - this->priv_size_traits().set_size(size_type(0)); - this->swap(x); - } - - //! Effects: to-do - //! - rbtree_impl& operator=(BOOST_RV_REF(rbtree_impl) x) - { this->swap(x); return *this; } - - //! Effects: Detaches all elements from this. The objects in the set - //! are not deleted (i.e. no destructors are called), but the nodes according to - //! the value_traits template parameter are reinitialized and thus can be reused. - //! - //! Complexity: Linear to elements contained in *this. - //! - //! Throws: Nothing. - ~rbtree_impl() + : tree_type(unique, b, e, cmp, v_traits) {} - //! Effects: Returns an iterator pointing to the beginning of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator begin() - { return iterator (node_traits::get_left(this->priv_header_ptr()), this); } + //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&) + rbtree_impl(BOOST_RV_REF(rbtree_impl) x) + : tree_type(::boost::move(static_cast(x))) + {} - //! Effects: Returns a const_iterator pointing to the beginning of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator begin() const - { return cbegin(); } + //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&) + rbtree_impl& operator=(BOOST_RV_REF(rbtree_impl) x) + { return static_cast(tree_type::operator=(::boost::move(static_cast(x)))); } - //! Effects: Returns a const_iterator pointing to the beginning of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cbegin() const - { return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree::~bstree() + ~rbtree_impl(); - //! Effects: Returns an iterator pointing to the end of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator end() - { return iterator (this->priv_header_ptr(), this); } + //! @copydoc ::boost::intrusive::bstree::begin() + iterator begin(); - //! Effects: Returns a const_iterator pointing to the end of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator end() const - { return cend(); } + //! @copydoc ::boost::intrusive::bstree::begin()const + const_iterator begin() const; - //! Effects: Returns a const_iterator pointing to the end of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cend() const - { return const_iterator (uncast(this->priv_header_ptr()), this); } + //! @copydoc ::boost::intrusive::bstree::cbegin()const + const_iterator cbegin() const; - //! Effects: Returns a reverse_iterator pointing to the beginning of the - //! reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rbegin() - { return reverse_iterator(end()); } + //! @copydoc ::boost::intrusive::bstree::end() + iterator end(); - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rbegin() const - { return const_reverse_iterator(end()); } + //! @copydoc ::boost::intrusive::bstree::end()const + const_iterator end() const; - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crbegin() const - { return const_reverse_iterator(end()); } + //! @copydoc ::boost::intrusive::bstree::cend()const + const_iterator cend() const; - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rend() - { return reverse_iterator(begin()); } + //! @copydoc ::boost::intrusive::bstree::rbegin() + reverse_iterator rbegin(); - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rend() const - { return const_reverse_iterator(begin()); } + //! @copydoc ::boost::intrusive::bstree::rbegin()const + const_reverse_iterator rbegin() const; - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crend() const - { return const_reverse_iterator(begin()); } + //! @copydoc ::boost::intrusive::bstree::crbegin()const + const_reverse_iterator crbegin() const; - //! Precondition: end_iterator must be a valid end iterator - //! of rbtree. - //! - //! Effects: Returns a const reference to the rbtree associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static rbtree_impl &container_from_end_iterator(iterator end_iterator) - { return priv_container_from_end_iterator(end_iterator); } + //! @copydoc ::boost::intrusive::bstree::rend() + reverse_iterator rend(); - //! Precondition: end_iterator must be a valid end const_iterator - //! of rbtree. - //! - //! Effects: Returns a const reference to the rbtree associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator) - { return priv_container_from_end_iterator(end_iterator); } + //! @copydoc ::boost::intrusive::bstree::rend()const + const_reverse_iterator rend() const; - //! Precondition: it must be a valid iterator - //! of rbtree. - //! - //! Effects: Returns a const reference to the tree associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static rbtree_impl &container_from_iterator(iterator it) - { return priv_container_from_iterator(it); } + //! @copydoc ::boost::intrusive::bstree::crend()const + const_reverse_iterator crend() const; - //! Precondition: it must be a valid end const_iterator - //! of rbtree. - //! - //! Effects: Returns a const reference to the tree associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static const rbtree_impl &container_from_iterator(const_iterator it) - { return priv_container_from_iterator(it); } + //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator) + static rbtree_impl &container_from_end_iterator(iterator end_iterator); - //! Effects: Returns the value_compare object used by the tree. - //! - //! Complexity: Constant. - //! - //! Throws: If value_compare copy-constructor throws. - value_compare value_comp() const - { return priv_comp(); } + //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator) + static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator); - //! Effects: Returns true if the container is empty. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - bool empty() const - { return node_algorithms::unique(this->priv_header_ptr()); } + //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator) + static rbtree_impl &container_from_iterator(iterator it); - //! Effects: Returns the number of elements stored in the tree. - //! - //! Complexity: Linear to elements contained in *this - //! if constant-time size option is disabled. Constant time otherwise. - //! - //! Throws: Nothing. - size_type size() const - { - if(constant_time_size) - return this->priv_size_traits().get_size(); - else{ - return (size_type)node_algorithms::size(this->priv_header_ptr()); - } - } + //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator) + static const rbtree_impl &container_from_iterator(const_iterator it); - //! Effects: Swaps the contents of two rbtrees. - //! - //! Complexity: Constant. - //! - //! Throws: If the comparison functor's swap call throws. - void swap(rbtree_impl& other) - { - //This can throw - using std::swap; - swap(priv_comp(), priv_comp()); - //These can't throw - node_algorithms::swap_tree(this->priv_header_ptr(), node_ptr(other.priv_header_ptr())); - if(constant_time_size){ - size_type backup = this->priv_size_traits().get_size(); - this->priv_size_traits().set_size(other.priv_size_traits().get_size()); - other.priv_size_traits().set_size(backup); - } - } + //! @copydoc ::boost::intrusive::bstree::key_comp()const + key_compare key_comp() const; - //! Requires: value must be an lvalue - //! - //! Effects: Inserts value into the tree before the upper bound. - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. - iterator insert_equal(reference value) - { - detail::key_nodeptr_comp - key_node_comp(priv_comp(), this); - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - iterator ret(node_algorithms::insert_equal_upper_bound - (this->priv_header_ptr(), to_insert, key_node_comp), this); - this->priv_size_traits().increment(); - return ret; - } + //! @copydoc ::boost::intrusive::bstree::value_comp()const + value_compare value_comp() const; - //! Requires: value must be an lvalue, and "hint" must be - //! a valid iterator. - //! - //! Effects: Inserts x into the tree, using "hint" as a hint to - //! where it will be inserted. If "hint" is the upper_bound - //! the insertion takes constant time (two comparisons in the worst case) - //! - //! Complexity: Logarithmic in general, but it is amortized - //! constant time if t is inserted immediately before hint. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. - iterator insert_equal(const_iterator hint, reference value) - { - detail::key_nodeptr_comp - key_node_comp(priv_comp(), this); - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - iterator ret(node_algorithms::insert_equal - (this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this); - this->priv_size_traits().increment(); - return ret; - } + //! @copydoc ::boost::intrusive::bstree::empty()const + bool empty() const; - //! Requires: Dereferencing iterator must yield an lvalue - //! of type value_type. - //! - //! Effects: Inserts a each element of a range into the tree - //! before the upper bound of the key of each element. - //! - //! Complexity: Insert range is in general O(N * log(N)), where N is the - //! size of the range. However, it is linear in N if the range is already sorted - //! by value_comp(). - //! - //! Throws: Nothing. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::bstree::size()const + size_type size() const; + + //! @copydoc ::boost::intrusive::bstree::swap + void swap(rbtree_impl& other); + + //! @copydoc ::boost::intrusive::bstree::clone_from + template + void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer); + + //! @copydoc ::boost::intrusive::bstree::insert_equal(reference) + iterator insert_equal(reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference) + iterator insert_equal(const_iterator hint, reference value); + + //! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator) template - void insert_equal(Iterator b, Iterator e) - { - iterator iend(this->end()); - for (; b != e; ++b) - this->insert_equal(iend, *b); - } + void insert_equal(Iterator b, Iterator e); - //! Requires: value must be an lvalue - //! - //! Effects: Inserts value into the tree if the value - //! is not already present. - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: Nothing. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. - std::pair insert_unique(reference value) - { - insert_commit_data commit_data; - std::pair ret = insert_unique_check(value, priv_comp(), commit_data); - if(!ret.second) - return ret; - return std::pair (insert_unique_commit(value, commit_data), true); - } + //! @copydoc ::boost::intrusive::bstree::insert_unique(reference) + std::pair insert_unique(reference value); - //! Requires: value must be an lvalue, and "hint" must be - //! a valid iterator - //! - //! Effects: Tries to insert x into the tree, using "hint" as a hint - //! to where it will be inserted. - //! - //! Complexity: Logarithmic in general, but it is amortized - //! constant time (two comparisons in the worst case) - //! if t is inserted immediately before hint. - //! - //! Throws: Nothing. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. - iterator insert_unique(const_iterator hint, reference value) - { - insert_commit_data commit_data; - std::pair ret = insert_unique_check(hint, value, priv_comp(), commit_data); - if(!ret.second) - return ret.first; - return insert_unique_commit(value, commit_data); - } + //! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference) + iterator insert_unique(const_iterator hint, reference value); - //! Requires: Dereferencing iterator must yield an lvalue - //! of type value_type. - //! - //! Effects: Tries to insert each element of a range into the tree. - //! - //! Complexity: Insert range is in general O(N * log(N)), where N is the - //! size of the range. However, it is linear in N if the range is already sorted - //! by value_comp(). - //! - //! Throws: Nothing. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. - template - void insert_unique(Iterator b, Iterator e) - { - if(this->empty()){ - iterator iend(this->end()); - for (; b != e; ++b) - this->insert_unique(iend, *b); - } - else{ - for (; b != e; ++b) - this->insert_unique(*b); - } - } - - //! Requires: key_value_comp must be a comparison function that induces - //! the same strict weak ordering as value_compare. The difference is that - //! key_value_comp compares an arbitrary key with the contained values. - //! - //! Effects: Checks if a value can be inserted in the container, using - //! a user provided key instead of the value itself. - //! - //! Returns: If there is an equivalent value - //! returns a pair containing an iterator to the already present value - //! and false. If the value can be inserted returns true in the returned - //! pair boolean and fills "commit_data" that is meant to be used with - //! the "insert_commit" function. - //! - //! Complexity: Average complexity is at most logarithmic. - //! - //! Throws: If the key_value_comp ordering function throws. Strong guarantee. - //! - //! Notes: This function is used to improve performance when constructing - //! a value_type is expensive: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! node that is used to impose the order is much cheaper to construct - //! than the value_type and this function offers the possibility to use that - //! part to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the value_type and use - //! "insert_commit" to insert the object in constant-time. This gives a total - //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_commit" only if no more - //! objects are inserted or erased from the container. + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&) template std::pair insert_unique_check - (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) - { - detail::key_nodeptr_comp - comp(key_value_comp, this); - std::pair ret = - (node_algorithms::insert_unique_check - (this->priv_header_ptr(), key, comp, commit_data)); - return std::pair(iterator(ret.first, this), ret.second); - } + (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data); - //! Requires: key_value_comp must be a comparison function that induces - //! the same strict weak ordering as value_compare. The difference is that - //! key_value_comp compares an arbitrary key with the contained values. - //! - //! Effects: Checks if a value can be inserted in the container, using - //! a user provided key instead of the value itself, using "hint" - //! as a hint to where it will be inserted. - //! - //! Returns: If there is an equivalent value - //! returns a pair containing an iterator to the already present value - //! and false. If the value can be inserted returns true in the returned - //! pair boolean and fills "commit_data" that is meant to be used with - //! the "insert_commit" function. - //! - //! Complexity: Logarithmic in general, but it's amortized - //! constant time if t is inserted immediately before hint. - //! - //! Throws: If the key_value_comp ordering function throws. Strong guarantee. - //! - //! Notes: This function is used to improve performance when constructing - //! a value_type is expensive: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! constructing that is used to impose the order is much cheaper to construct - //! than the value_type and this function offers the possibility to use that key - //! to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the value_type and use - //! "insert_commit" to insert the object in constant-time. This can give a total - //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_commit" only if no more - //! objects are inserted or erased from the container. + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&) template std::pair insert_unique_check (const_iterator hint, const KeyType &key - ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) - { - detail::key_nodeptr_comp - comp(key_value_comp, this); - std::pair ret = - (node_algorithms::insert_unique_check - (this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data)); - return std::pair(iterator(ret.first, this), ret.second); - } + ,KeyValueCompare key_value_comp, insert_commit_data &commit_data); - //! Requires: value must be an lvalue of type value_type. commit_data - //! must have been obtained from a previous call to "insert_check". - //! No objects should have been inserted or erased from the container between - //! the "insert_check" that filled "commit_data" and the call to "insert_commit". - //! - //! Effects: Inserts the value in the avl_set using the information obtained - //! from the "commit_data" that a previous "insert_check" filled. - //! - //! Returns: An iterator to the newly inserted object. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function has only sense if a "insert_check" has been - //! previously executed to fill "commit_data". No value should be inserted or - //! erased between the "insert_check" and "insert_commit" calls. - iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) - { - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - node_algorithms::insert_unique_commit - (this->priv_header_ptr(), to_insert, commit_data); - this->priv_size_traits().increment(); - return iterator(to_insert, this); - } + //! @copydoc ::boost::intrusive::bstree::insert_unique_commit + iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); - //! Requires: value must be an lvalue, "pos" must be - //! a valid iterator (or end) and must be the succesor of value - //! once inserted according to the predicate - //! - //! Effects: Inserts x into the tree before "pos". - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if "pos" is not - //! the successor of "value" tree ordering invariant will be broken. - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - iterator insert_before(const_iterator pos, reference value) - { - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_before - (this->priv_header_ptr(), pos.pointed_node(), to_insert), this); - } + //! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator) + template + void insert_unique(Iterator b, Iterator e); - //! Requires: value must be an lvalue, and it must be no less - //! than the greatest inserted key - //! - //! Effects: Inserts x into the tree in the last position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! less than the greatest inserted key tree ordering invariant will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_back(reference value) - { - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - this->priv_size_traits().increment(); - node_algorithms::push_back(this->priv_header_ptr(), to_insert); - } + //! @copydoc ::boost::intrusive::bstree::insert_before + iterator insert_before(const_iterator pos, reference value); - //! Requires: value must be an lvalue, and it must be no greater - //! than the minimum inserted key - //! - //! Effects: Inserts x into the tree in the first position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! greater than the minimum inserted key tree ordering invariant will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_front(reference value) - { - node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - this->priv_size_traits().increment(); - node_algorithms::push_front(this->priv_header_ptr(), to_insert); - } + //! @copydoc ::boost::intrusive::bstree::push_back + void push_back(reference value); - //! Effects: Erases the element pointed to by pos. - //! - //! Complexity: Average complexity for erase element is constant time. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) - { - const_iterator ret(i); - ++ret; - node_ptr to_erase(i.pointed_node()); - if(safemode_or_autounlink) - BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); - node_algorithms::erase(this->priv_header_ptr(), to_erase); - this->priv_size_traits().decrement(); - if(safemode_or_autounlink) - node_algorithms::init(to_erase); - return ret.unconst(); - } + //! @copydoc ::boost::intrusive::bstree::push_front + void push_front(reference value); - //! Effects: Erases the range pointed to by b end e. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) - { size_type n; return private_erase(b, e, n); } + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator) + iterator erase(const_iterator i); - //! Effects: Erases all the elements with the given value. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + N). - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - size_type erase(const_reference value) - { return this->erase(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator) + iterator erase(const_iterator b, const_iterator e); - //! Effects: Erases all the elements with the given key. - //! according to the comparison functor "comp". - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + N). - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::bstree::erase(const_reference) + size_type erase(const_reference value); + + //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare) template - size_type erase(const KeyType& key, KeyValueCompare comp - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { - std::pair p = this->equal_range(key, comp); - size_type n; - private_erase(p.first, p.second, n); - return n; - } + size_type erase(const KeyType& key, KeyValueCompare comp); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases the element pointed to by pos. - //! Disposer::operator()(pointer) is called for the removed element. - //! - //! Complexity: Average complexity for erase element is constant time. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer) - { - node_ptr to_erase(i.pointed_node()); - iterator ret(this->erase(i)); - disposer(get_real_value_traits().to_value_ptr(to_erase)); - return ret; - } + iterator erase_and_dispose(const_iterator i, Disposer disposer); - #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(iterator i, Disposer disposer) - { return this->erase_and_dispose(const_iterator(i), disposer); } - #endif + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given value. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + N). - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer) template - size_type erase_and_dispose(const_reference value, Disposer disposer) - { - std::pair p = this->equal_range(value); - size_type n; - private_erase(p.first, p.second, n, disposer); - return n; - } + size_type erase_and_dispose(const_reference value, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases the range pointed to by b end e. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. - template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) - { size_type n; return private_erase(b, e, n, disposer); } - - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given key. - //! according to the comparison functor "comp". - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + N). - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer) template - size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { - std::pair p = this->equal_range(key, comp); - size_type n; - private_erase(p.first, p.second, n, disposer); - return n; - } + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer); - //! Effects: Erases all of the elements. - //! - //! Complexity: Linear to the number of elements on the container. - //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - void clear() - { - if(safemode_or_autounlink){ - this->clear_and_dispose(detail::null_disposer()); - } - else{ - node_algorithms::init_header(this->priv_header_ptr()); - this->priv_size_traits().set_size(0); - } - } + //! @copydoc ::boost::intrusive::bstree::clear + void clear(); - //! Effects: Erases all of the elements calling disposer(p) for - //! each node to be erased. - //! Complexity: Average complexity for is at most O(log(size() + N)), - //! where N is the number of elements in the container. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. Calls N times to disposer functor. + //! @copydoc ::boost::intrusive::bstree::clear_and_dispose template - void clear_and_dispose(Disposer disposer) - { - node_algorithms::clear_and_dispose(this->priv_header_ptr() - , detail::node_disposer(disposer, this)); - node_algorithms::init_header(this->priv_header_ptr()); - this->priv_size_traits().set_size(0); - } + void clear_and_dispose(Disposer disposer); - //! Effects: Returns the number of contained elements with the given value - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given value. - //! - //! Throws: Nothing. - size_type count(const_reference value) const - { return this->count(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::count(const_reference)const + size_type count(const_reference value) const; - //! Effects: Returns the number of contained elements with the given key - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given key. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const template - size_type count(const KeyType &key, KeyValueCompare comp) const - { - std::pair ret = this->equal_range(key, comp); - return std::distance(ret.first, ret.second); - } - - //! Effects: Returns an iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - iterator lower_bound(const_reference value) - { return this->lower_bound(value, priv_comp()); } - - //! Effects: Returns an iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - const_iterator lower_bound(const_reference value) const - { return this->lower_bound(value, priv_comp()); } - - //! Effects: Returns an iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + size_type count(const KeyType& key, KeyValueCompare comp) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference) + iterator lower_bound(const_reference value); + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare) template - iterator lower_bound(const KeyType &key, KeyValueCompare comp) - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return iterator(node_algorithms::lower_bound - (this->priv_header_ptr(), key, key_node_comp), this); - } + iterator lower_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns a const iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const + const_iterator lower_bound(const_reference value) const; + + //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const template - const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return const_iterator(node_algorithms::lower_bound - (this->priv_header_ptr(), key, key_node_comp), this); - } + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - iterator upper_bound(const_reference value) - { return this->upper_bound(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference) + iterator upper_bound(const_reference value); - //! Effects: Returns an iterator to the first element whose - //! key is greater than k according to comp or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare) template - iterator upper_bound(const KeyType &key, KeyValueCompare comp) - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return iterator(node_algorithms::upper_bound - (this->priv_header_ptr(), key, key_node_comp), this); - } + iterator upper_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - const_iterator upper_bound(const_reference value) const - { return this->upper_bound(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const + const_iterator upper_bound(const_reference value) const; - //! Effects: Returns an iterator to the first element whose - //! key is greater than k according to comp or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const template - const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return const_iterator(node_algorithms::upper_bound - (this->priv_header_ptr(), key, key_node_comp), this); - } + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds an iterator to the first element whose key is - //! k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - iterator find(const_reference value) - { return this->find(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::find(const_reference) + iterator find(const_reference value); - //! Effects: Finds an iterator to the first element whose key is - //! k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare) template - iterator find(const KeyType &key, KeyValueCompare comp) - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return iterator - (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); - } + iterator find(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a const_iterator to the first element whose key is - //! k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - const_iterator find(const_reference value) const - { return this->find(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::find(const_reference)const + const_iterator find(const_reference value) const; - //! Effects: Finds a const_iterator to the first element whose key is - //! k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const template - const_iterator find(const KeyType &key, KeyValueCompare comp) const - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - return const_iterator - (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); - } + const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - std::pair equal_range(const_reference value) - { return this->equal_range(value, priv_comp()); } + //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference) + std::pair equal_range(const_reference value); - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType &key, KeyValueCompare comp) - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - std::pair ret - (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); - return std::pair(iterator(ret.first, this), iterator(ret.second, this)); - } + std::pair equal_range(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const - { return this->equal_range(value, priv_comp()); } + equal_range(const_reference value) const; - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType &key, KeyValueCompare comp) const - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - std::pair ret - (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); - return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); - } + equal_range(const KeyType& key, KeyValueCompare comp) const; - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. + //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range - (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) - { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed); - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool) template std::pair bounded_range - (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - std::pair ret - (node_algorithms::bounded_range - (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); - return std::pair(iterator(ret.first, this), iterator(ret.second, this)); - } + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed); - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. - std::pair bounded_range - (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const - { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const; - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const template - std::pair bounded_range - (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const - { - detail::key_nodeptr_comp - key_node_comp(comp, this); - std::pair ret - (node_algorithms::bounded_range - (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); - return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); - } + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const; - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! Cloner should yield to nodes equivalent to the original nodes. - //! - //! Effects: Erases all the elements from *this - //! calling Disposer::operator()(pointer), clones all the - //! elements from src calling Cloner::operator()(const_reference ) - //! and inserts them on *this. Copies the predicate from the source container. - //! - //! If cloner throws, all cloned elements are unlinked and disposed - //! calling Disposer::operator()(pointer). - //! - //! Complexity: Linear to erased plus inserted elements. - //! - //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. - template - void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer) - { - this->clear_and_dispose(disposer); - if(!src.empty()){ - detail::exception_disposer - rollback(*this, disposer); - node_algorithms::clone - (const_node_ptr(src.priv_header_ptr()) - ,node_ptr(this->priv_header_ptr()) - ,detail::node_cloner(cloner, this) - ,detail::node_disposer(disposer, this)); - this->priv_size_traits().set_size(src.priv_size_traits().get_size()); - this->priv_comp() = src.priv_comp(); - rollback.release(); - } - } + //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference) + static iterator s_iterator_to(reference value); - //! Effects: Unlinks the leftmost node from the tree. - //! - //! Complexity: Average complexity is constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function breaks the tree and the tree can - //! only be used for more unlink_leftmost_without_rebalance calls. - //! This function is normally used to achieve a step by step - //! controlled destruction of the tree. - pointer unlink_leftmost_without_rebalance() - { - node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance - (this->priv_header_ptr())); - if(!to_be_disposed) - return 0; - this->priv_size_traits().decrement(); - if(safemode_or_autounlink)//If this is commented does not work with normal_link - node_algorithms::init(to_be_disposed); - return get_real_value_traits().to_value_ptr(to_be_disposed); - } + //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value); - //! Requires: replace_this must be a valid iterator of *this - //! and with_this must not be inserted in any tree. - //! - //! Effects: Replaces replace_this in its position in the - //! tree with with_this. The tree does not need to be rebalanced. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! with_this is not equivalent to *replace_this according to the - //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing or comparison is needed. - void replace_node(iterator replace_this, reference with_this) - { - node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) - , this->priv_header_ptr() - , get_real_value_traits().to_node_ptr(with_this)); - if(safemode_or_autounlink) - node_algorithms::init(replace_this.pointed_node()); - } + //! @copydoc ::boost::intrusive::bstree::iterator_to(reference) + iterator iterator_to(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static iterator s_iterator_to(reference value) - { - BOOST_STATIC_ASSERT((!stateful_value_traits)); - return iterator (value_traits::to_node_ptr(value), 0); - } + //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const; - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static const_iterator s_iterator_to(const_reference value) - { - BOOST_STATIC_ASSERT((!stateful_value_traits)); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); - } + //! @copydoc ::boost::intrusive::bstree::init_node(reference) + static void init_node(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator iterator_to(reference value) - { return iterator (value_traits::to_node_ptr(value), this); } + //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance + pointer unlink_leftmost_without_rebalance(); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator iterator_to(const_reference value) const - { return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); } + //! @copydoc ::boost::intrusive::bstree::replace_node + void replace_node(iterator replace_this, reference with_this); - //! Requires: value shall not be in a tree. - //! - //! Effects: init_node puts the hook of a value in a well-known default - //! state. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - //! - //! Note: This function puts the hook in the well-known default state - //! used by auto_unlink and safe hooks. - static void init_node(reference value) - { node_algorithms::init(value_traits::to_node_ptr(value)); } - - //! Effects: removes "value" from the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic time. - //! - //! Note: This static function is only usable with non-constant - //! time size containers that have stateless comparison functors. - //! - //! If the user calls - //! this function with a constant time size container or stateful comparison - //! functor a compilation error will be issued. - static void remove_node(reference value) - { - BOOST_STATIC_ASSERT((!constant_time_size)); - node_ptr to_remove(value_traits::to_node_ptr(value)); - node_algorithms::unlink(to_remove); - if(safemode_or_autounlink) - node_algorithms::init(to_remove); - } - - /// @cond - private: - template - iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer) - { - for(n = 0; b != e; ++n) - this->erase_and_dispose(b++, disposer); - return b.unconst(); - } - - iterator private_erase(const_iterator b, const_iterator e, size_type &n) - { - for(n = 0; b != e; ++n) - this->erase(b++); - return b.unconst(); - } - /// @endcond - - private: - static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) - { - header_plus_size *r = detail::parent_from_member - ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_); - node_plus_pred_t *n = detail::parent_from_member - (r, &node_plus_pred_t::header_plus_size_); - data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); - rbtree_impl *rb = detail::parent_from_member(d, &rbtree_impl::data_); - return *rb; - } - - static rbtree_impl &priv_container_from_iterator(const const_iterator &it) - { return priv_container_from_end_iterator(it.end_iterator_from_it()); } + //! @copydoc ::boost::intrusive::bstree::remove_node + void remove_node(reference value); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED }; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template -#else -template -#endif -inline bool operator< -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } +bool operator< (const rbtree_impl &x, const rbtree_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -bool operator== -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ - typedef rbtree_impl tree_type; - typedef typename tree_type::const_iterator const_iterator; +bool operator==(const rbtree_impl &x, const rbtree_impl &y); - if(tree_type::constant_time_size && x.size() != y.size()){ - return false; - } - const_iterator end1 = x.end(); - const_iterator i1 = x.begin(); - const_iterator i2 = y.begin(); - if(tree_type::constant_time_size){ - while (i1 != end1 && *i1 == *i2) { - ++i1; - ++i2; - } - return i1 == end1; - } - else{ - const_iterator end2 = y.end(); - while (i1 != end1 && i2 != end2 && *i1 == *i2) { - ++i1; - ++i2; - } - return i1 == end1 && i2 == end2; - } -} - -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator!= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ return !(x == y); } +bool operator!= (const rbtree_impl &x, const rbtree_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator> -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ return y < x; } +bool operator>(const rbtree_impl &x, const rbtree_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator<= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ return !(y < x); } +bool operator<=(const rbtree_impl &x, const rbtree_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator>= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const rbtree_impl &x, const rbtree_impl &y) -#else -(const rbtree_impl &x, const rbtree_impl &y) -#endif -{ return !(x < y); } +bool operator>=(const rbtree_impl &x, const rbtree_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline void swap -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(rbtree_impl &x, rbtree_impl &y) -#else -(rbtree_impl &x, rbtree_impl &y) -#endif -{ x.swap(y); } +void swap(rbtree_impl &x, rbtree_impl &y); -/// @cond -#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template -#else -template -#endif -struct make_rbtree_opt -{ - typedef typename pack_options - < set_defaults, - #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4 - #else - Options... - #endif - >::type packed_options; - typedef typename detail::get_value_traits - ::type value_traits; - - typedef setopt - < value_traits - , typename packed_options::compare - , typename packed_options::size_type - , packed_options::constant_time_size - > type; -}; -/// @endcond +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Helper metafunction to define a \c rbtree that yields to the same type when the //! same options (either explicitly or implicitly) are used. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_rbtree { /// @cond + typedef typename pack_options + < rbtree_defaults, + #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + typedef rbtree_impl - < typename make_rbtree_opt::type - > implementation_defined; + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > implementation_defined; /// @endcond typedef implementation_defined type; }; + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) @@ -1738,12 +486,14 @@ class rbtree typedef typename Base::real_value_traits real_value_traits; typedef typename Base::iterator iterator; typedef typename Base::const_iterator const_iterator; + typedef typename Base::reverse_iterator reverse_iterator; + typedef typename Base::const_reverse_iterator const_reverse_iterator; //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); - rbtree( const value_compare &cmp = value_compare() - , const value_traits &v_traits = value_traits()) + explicit rbtree( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} @@ -1759,7 +509,7 @@ class rbtree {} rbtree& operator=(BOOST_RV_REF(rbtree) x) - { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + { return static_cast(this->Base::operator=(::boost::move(static_cast(x)))); } static rbtree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1767,16 +517,15 @@ class rbtree static const rbtree &container_from_end_iterator(const_iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static rbtree &container_from_it(iterator it) + static rbtree &container_from_iterator(iterator it) { return static_cast(Base::container_from_iterator(it)); } - static const rbtree &container_from_it(const_iterator it) + static const rbtree &container_from_iterator(const_iterator it) { return static_cast(Base::container_from_iterator(it)); } }; #endif - } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/rbtree_algorithms.hpp b/cpp/BoostParts/boost/intrusive/rbtree_algorithms.hpp index fc28630d..38a5cdcf 100644 --- a/cpp/BoostParts/boost/intrusive/rbtree_algorithms.hpp +++ b/cpp/BoostParts/boost/intrusive/rbtree_algorithms.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012. +// (C) Copyright Ion Gaztanaga 2006-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -55,12 +55,50 @@ #include #include -#include +#include #include namespace boost { namespace intrusive { +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +template +struct rbtree_node_cloner + : private detail::ebo_functor_holder +{ + typedef typename NodeTraits::node_ptr node_ptr; + typedef detail::ebo_functor_holder base_t; + + rbtree_node_cloner(F f) + : base_t(f) + {} + + node_ptr operator()(const node_ptr & p) + { + node_ptr n = base_t::get()(p); + NodeTraits::set_color(n, NodeTraits::get_color(p)); + return n; + } +}; + +template +struct rbtree_erase_fixup +{ + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::color color; + + void operator()(const node_ptr & to_erase, const node_ptr & successor) + { + //Swap color of y and z + color tmp(NodeTraits::get_color(successor)); + NodeTraits::set_color(successor, NodeTraits::get_color(to_erase)); + NodeTraits::set_color(to_erase, tmp); + } +}; + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! rbtree_algorithms provides basic algorithms to manipulate //! nodes forming a red-black tree. The insertion and deletion algorithms are //! based on those in Cormen, Leiserson, and Rivest, Introduction to Algorithms @@ -82,7 +120,7 @@ namespace intrusive { //! //! Typedefs: //! -//! node: The type of the node that forms the circular list +//! node: The type of the node that forms the binary search tree //! //! node_ptr: A pointer to a node //! @@ -113,6 +151,9 @@ namespace intrusive { //! static color red(); template class rbtree_algorithms + #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_algorithms + #endif { public: typedef NodeTraits node_traits; @@ -124,167 +165,71 @@ class rbtree_algorithms /// @cond private: - typedef detail::tree_algorithms tree_algorithms; + typedef bstree_algorithms bstree_algo; - template - struct rbtree_node_cloner - : private detail::ebo_functor_holder - { - typedef detail::ebo_functor_holder base_t; - - rbtree_node_cloner(F f) - : base_t(f) - {} - - node_ptr operator()(const node_ptr & p) - { - node_ptr n = base_t::get()(p); - NodeTraits::set_color(n, NodeTraits::get_color(p)); - return n; - } - }; - - struct rbtree_erase_fixup - { - void operator()(const node_ptr & to_erase, const node_ptr & successor) - { - //Swap color of y and z - color tmp(NodeTraits::get_color(successor)); - NodeTraits::set_color(successor, NodeTraits::get_color(to_erase)); - NodeTraits::set_color(to_erase, tmp); - } - }; - - static node_ptr uncast(const const_node_ptr & ptr) - { return pointer_traits::const_cast_from(ptr); } /// @endcond public: - static node_ptr begin_node(const const_node_ptr & header) - { return tree_algorithms::begin_node(header); } - - static node_ptr end_node(const const_node_ptr & header) - { return tree_algorithms::end_node(header); } //! This type is the information that will be //! filled by insert_unique_check - typedef typename tree_algorithms::insert_commit_data insert_commit_data; + typedef typename bstree_algo::insert_commit_data insert_commit_data; - //! Requires: header1 and header2 must be the header nodes - //! of two trees. - //! - //! Effects: Swaps two trees. After the function header1 will contain - //! links to the second tree and header2 will have links to the first tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - static void swap_tree(const node_ptr & header1, const node_ptr & header2) - { return tree_algorithms::swap_tree(header1, header2); } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! Requires: node1 and node2 can't be header nodes - //! of two trees. - //! - //! Effects: Swaps two nodes. After the function node1 will be inserted - //! in the position node2 before the function. node2 will be inserted in the - //! position node1 had before the function. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! node1 and node2 are not equivalent according to the ordering rules. - //! - //!Experimental function + //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&) + static node_ptr get_header(const const_node_ptr & n); + + //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node + static node_ptr begin_node(const const_node_ptr & header); + + //! @copydoc ::boost::intrusive::bstree_algorithms::end_node + static node_ptr end_node(const const_node_ptr & header); + + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree + static void swap_tree(const node_ptr & header1, const node_ptr & header2); + + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&) static void swap_nodes(const node_ptr & node1, const node_ptr & node2) { if(node1 == node2) return; - node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2)); + node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2)); swap_nodes(node1, header1, node2, header2); } - //! Requires: node1 and node2 can't be header nodes - //! of two trees with header header1 and header2. - //! - //! Effects: Swaps two nodes. After the function node1 will be inserted - //! in the position node2 before the function. node2 will be inserted in the - //! position node1 had before the function. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! node1 and node2 are not equivalent according to the ordering rules. - //! - //!Experimental function + //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&) static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) { if(node1 == node2) return; - tree_algorithms::swap_nodes(node1, header1, node2, header2); + bstree_algo::swap_nodes(node1, header1, node2, header2); //Swap color color c = NodeTraits::get_color(node1); NodeTraits::set_color(node1, NodeTraits::get_color(node2)); NodeTraits::set_color(node2, c); } - //! Requires: node_to_be_replaced must be inserted in a tree - //! and new_node must not be inserted in a tree. - //! - //! Effects: Replaces node_to_be_replaced in its position in the - //! tree with new_node. The tree does not need to be rebalanced - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! new_node is not equivalent to node_to_be_replaced according to the - //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing and comparison is needed. - //! - //!Experimental function + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&) static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) { if(node_to_be_replaced == new_node) return; - replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node); + replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node); } - //! Requires: node_to_be_replaced must be inserted in a tree - //! with header "header" and new_node must not be inserted in a tree. - //! - //! Effects: Replaces node_to_be_replaced in its position in the - //! tree with new_node. The tree does not need to be rebalanced - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! new_node is not equivalent to node_to_be_replaced according to the - //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing or comparison is needed. - //! - //!Experimental function + //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&) static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) { - tree_algorithms::replace_node(node_to_be_replaced, header, new_node); + bstree_algo::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); } - //! Requires: node is a tree node but not the header. - //! - //! Effects: Unlinks the node and rebalances the tree. - //! - //! Complexity: Average complexity is constant time. - //! - //! Throws: Nothing. - static void unlink(const node_ptr & node) + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&) + static void unlink(const node_ptr& node) { node_ptr x = NodeTraits::get_parent(node); if(x){ @@ -294,517 +239,176 @@ class rbtree_algorithms } } - //! Requires: header is the header of a tree. - //! - //! Effects: Unlinks the leftmost node from the tree, and - //! updates the header link to the new leftmost node. - //! - //! Complexity: Average complexity is constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function breaks the tree and the tree can - //! only be used for more unlink_leftmost_without_rebalance calls. - //! This function is normally used to achieve a step by step - //! controlled destruction of the tree. - static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header) - { return tree_algorithms::unlink_leftmost_without_rebalance(header); } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance + static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header); - //! Requires: node is a node of the tree or an node initialized - //! by init(...). - //! - //! Effects: Returns true if the node is initialized by init(). - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - static bool unique(const const_node_ptr & node) - { return tree_algorithms::unique(node); } + //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&) + static bool unique(const const_node_ptr & node); - //! Requires: node is a node of the tree but it's not the header. - //! - //! Effects: Returns the number of nodes of the subtree. - //! - //! Complexity: Linear time. - //! - //! Throws: Nothing. - static std::size_t count(const const_node_ptr & node) - { return tree_algorithms::count(node); } + //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&) + static std::size_t size(const const_node_ptr & header); - //! Requires: header is the header node of the tree. - //! - //! Effects: Returns the number of nodes above the header. - //! - //! Complexity: Linear time. - //! - //! Throws: Nothing. - static std::size_t size(const const_node_ptr & header) - { return tree_algorithms::size(header); } + //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&) + static node_ptr next_node(const node_ptr & node); - //! Requires: p is a node from the tree except the header. - //! - //! Effects: Returns the next node of the tree. - //! - //! Complexity: Average constant time. - //! - //! Throws: Nothing. - static node_ptr next_node(const node_ptr & p) - { return tree_algorithms::next_node(p); } + //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&) + static node_ptr prev_node(const node_ptr & node); - //! Requires: p is a node from the tree except the leftmost node. - //! - //! Effects: Returns the previous node of the tree. - //! - //! Complexity: Average constant time. - //! - //! Throws: Nothing. - static node_ptr prev_node(const node_ptr & p) - { return tree_algorithms::prev_node(p); } + //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&) + static void init(const node_ptr & node); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! Requires: node must not be part of any tree. - //! - //! Effects: After the function unique(node) == true. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Nodes: If node is inserted in a tree, this function corrupts the tree. - static void init(const node_ptr & node) - { tree_algorithms::init(node); } - - //! Requires: node must not be part of any tree. - //! - //! Effects: Initializes the header to represent an empty tree. - //! unique(header) == true. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Nodes: If node is inserted in a tree, this function corrupts the tree. + //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&) static void init_header(const node_ptr & header) { - tree_algorithms::init_header(header); + bstree_algo::init_header(header); NodeTraits::set_color(header, NodeTraits::red()); } - //! Requires: header must be the header of a tree, z a node - //! of that tree and z != header. - //! - //! Effects: Erases node "z" from the tree with header "header". - //! - //! Complexity: Amortized constant time. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&) static node_ptr erase(const node_ptr & header, const node_ptr & z) { - typename tree_algorithms::data_for_rebalance info; - tree_algorithms::erase(header, z, rbtree_erase_fixup(), info); - node_ptr x = info.x; - node_ptr x_parent = info.x_parent; + typename bstree_algo::data_for_rebalance info; + bstree_algo::erase(header, z, rbtree_erase_fixup(), info); //Rebalance rbtree if(NodeTraits::get_color(z) != NodeTraits::red()){ - rebalance_after_erasure(header, x, x_parent); + rebalance_after_erasure(header, info.x, info.x_parent); } return z; } - //! Requires: "cloner" must be a function - //! object taking a node_ptr and returning a new cloned node of it. "disposer" must - //! take a node_ptr and shouldn't throw. - //! - //! Effects: First empties target tree calling - //! void disposer::operator()(const node_ptr &) for every node of the tree - //! except the header. - //! - //! Then, duplicates the entire tree pointed by "source_header" cloning each - //! source node with node_ptr Cloner::operator()(const node_ptr &) to obtain - //! the nodes of the target tree. If "cloner" throws, the cloned target nodes - //! are disposed using void disposer(const node_ptr &). - //! - //! Complexity: Linear to the number of element of the source tree plus the. - //! number of elements of tree target tree when calling this function. - //! - //! Throws: If cloner functor throws. If this happens target nodes are disposed. + //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer) template static void clone (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) { - rbtree_node_cloner new_cloner(cloner); - tree_algorithms::clone(source_header, target_header, new_cloner, disposer); + rbtree_node_cloner new_cloner(cloner); + bstree_algo::clone(source_header, target_header, new_cloner, disposer); } - //! Requires: "disposer" must be an object function - //! taking a node_ptr parameter and shouldn't throw. - //! - //! Effects: Empties the target tree calling - //! void disposer::operator()(const node_ptr &) for every node of the tree - //! except the header. - //! - //! Complexity: Linear to the number of element of the source tree plus the. - //! number of elements of tree target tree when calling this function. - //! - //! Throws: If cloner functor throws. If this happens target nodes are disposed. + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer) template - static void clear_and_dispose(const node_ptr & header, Disposer disposer) - { tree_algorithms::clear_and_dispose(header, disposer); } + static void clear_and_dispose(const node_ptr & header, Disposer disposer); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. - //! - //! Effects: Returns an node_ptr to the first element that is - //! not less than "key" according to "comp" or "header" if that element does - //! not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) template static node_ptr lower_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) - { return tree_algorithms::lower_bound(header, key, comp); } + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. - //! - //! Effects: Returns an node_ptr to the first element that is greater - //! than "key" according to "comp" or "header" if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) template static node_ptr upper_bound - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) - { return tree_algorithms::upper_bound(header, key, comp); } + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. - //! - //! Effects: Returns an node_ptr to the element that is equivalent to - //! "key" according to "comp" or "header" if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare) template static node_ptr find - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) - { return tree_algorithms::find(header, key, comp); } + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. - //! - //! Effects: Returns an a pair of node_ptr delimiting a range containing - //! all elements that are equivalent to "key" according to "comp" or an - //! empty range that indicates the position where those elements would be - //! if they there are no equivalent elements. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) template static std::pair equal_range - (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) - { return tree_algorithms::equal_range(header, key, comp); } + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) template static std::pair bounded_range (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp - , bool left_closed, bool right_closed) - { return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } + , bool left_closed, bool right_closed); - //! Requires: "h" must be the header node of a tree. - //! NodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. NodePtrCompare compares two node_ptrs. - //! - //! Effects: Inserts new_node into the tree before the upper bound - //! according to "comp". - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + template + static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare) template static node_ptr insert_equal_upper_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { - tree_algorithms::insert_equal_upper_bound(h, new_node, comp); + bstree_algo::insert_equal_upper_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! Requires: "h" must be the header node of a tree. - //! NodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. NodePtrCompare compares two node_ptrs. - //! - //! Effects: Inserts new_node into the tree before the lower bound - //! according to "comp". - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare) template static node_ptr insert_equal_lower_bound (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { - tree_algorithms::insert_equal_lower_bound(h, new_node, comp); + bstree_algo::insert_equal_lower_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); return new_node; } - //! Requires: "header" must be the header node of a tree. - //! NodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from - //! the "header"'s tree. - //! - //! Effects: Inserts new_node into the tree, using "hint" as a hint to - //! where it will be inserted. If "hint" is the upper_bound - //! the insertion takes constant time (two comparisons in the worst case). - //! - //! Complexity: Logarithmic in general, but it is amortized - //! constant time if new_node is inserted immediately before "hint". - //! - //! Throws: If "comp" throws. + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare) template static node_ptr insert_equal (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) { - tree_algorithms::insert_equal(header, hint, new_node, comp); + bstree_algo::insert_equal(header, hint, new_node, comp); rebalance_after_insertion(header, new_node); return new_node; } - //! Requires: "header" must be the header node of a tree. - //! "pos" must be a valid iterator or header (end) node. - //! "pos" must be an iterator pointing to the successor to "new_node" - //! once inserted according to the order of already inserted nodes. This function does not - //! check "pos" and this precondition must be guaranteed by the caller. - //! - //! Effects: Inserts new_node into the tree before "pos". - //! - //! Complexity: Constant-time. - //! - //! Throws: Nothing. - //! - //! Note: If "pos" is not the successor of the newly inserted "new_node" - //! tree invariants might be broken. + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&) static node_ptr insert_before (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) { - tree_algorithms::insert_before(header, pos, new_node); + bstree_algo::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); return new_node; } - //! Requires: "header" must be the header node of a tree. - //! "new_node" must be, according to the used ordering no less than the - //! greatest inserted key. - //! - //! Effects: Inserts new_node into the tree before "pos". - //! - //! Complexity: Constant-time. - //! - //! Throws: Nothing. - //! - //! Note: If "new_node" is less than the greatest inserted key - //! tree invariants are broken. This function is slightly faster than - //! using "insert_before". + //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&) static void push_back(const node_ptr & header, const node_ptr & new_node) { - tree_algorithms::push_back(header, new_node); + bstree_algo::push_back(header, new_node); rebalance_after_insertion(header, new_node); } - //! Requires: "header" must be the header node of a tree. - //! "new_node" must be, according to the used ordering, no greater than the - //! lowest inserted key. - //! - //! Effects: Inserts new_node into the tree before "pos". - //! - //! Complexity: Constant-time. - //! - //! Throws: Nothing. - //! - //! Note: If "new_node" is greater than the lowest inserted key - //! tree invariants are broken. This function is slightly faster than - //! using "insert_before". + //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&) static void push_front(const node_ptr & header, const node_ptr & new_node) { - tree_algorithms::push_front(header, new_node); + bstree_algo::push_front(header, new_node); rebalance_after_insertion(header, new_node); } - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. NodePtrCompare compares KeyType with a node_ptr. - //! - //! Effects: Checks if there is an equivalent node to "key" in the - //! tree according to "comp" and obtains the needed information to realize - //! a constant-time node insertion if there is no equivalent node. - //! - //! Returns: If there is an equivalent value - //! returns a pair containing a node_ptr to the already present node - //! and false. If there is not equivalent key can be inserted returns true - //! in the returned pair's boolean and fills "commit_data" that is meant to - //! be used with the "insert_commit" function to achieve a constant-time - //! insertion function. - //! - //! Complexity: Average complexity is at most logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Notes: This function is used to improve performance when constructing - //! a node is expensive and the user does not want to have two equivalent nodes - //! in the tree: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! node that is used to impose the order is much cheaper to construct - //! than the node and this function offers the possibility to use that part - //! to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the node and use - //! "insert_commit" to insert the node in constant-time. This gives a total - //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_unique_commit" only - //! if no more objects are inserted or erased from the set. + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const const_node_ptr & header, const KeyType &key - ,KeyNodePtrCompare comp, insert_commit_data &commit_data) - { return tree_algorithms::insert_unique_check(header, key, comp, commit_data); } + ,KeyNodePtrCompare comp, insert_commit_data &commit_data); - //! Requires: "header" must be the header node of a tree. - //! KeyNodePtrCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. NodePtrCompare compares KeyType with a node_ptr. - //! "hint" is node from the "header"'s tree. - //! - //! Effects: Checks if there is an equivalent node to "key" in the - //! tree according to "comp" using "hint" as a hint to where it should be - //! inserted and obtains the needed information to realize - //! a constant-time node insertion if there is no equivalent node. - //! If "hint" is the upper_bound the function has constant time - //! complexity (two comparisons in the worst case). - //! - //! Returns: If there is an equivalent value - //! returns a pair containing a node_ptr to the already present node - //! and false. If there is not equivalent key can be inserted returns true - //! in the returned pair's boolean and fills "commit_data" that is meant to - //! be used with the "insert_commit" function to achieve a constant-time - //! insertion function. - //! - //! Complexity: Average complexity is at most logarithmic, but it is - //! amortized constant time if new_node should be inserted immediately before "hint". - //! - //! Throws: If "comp" throws. - //! - //! Notes: This function is used to improve performance when constructing - //! a node is expensive and the user does not want to have two equivalent nodes - //! in the tree: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! node that is used to impose the order is much cheaper to construct - //! than the node and this function offers the possibility to use that part - //! to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the node and use - //! "insert_commit" to insert the node in constant-time. This gives a total - //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_unique_commit" only - //! if no more objects are inserted or erased from the set. + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&) template static std::pair insert_unique_check (const const_node_ptr & header, const node_ptr &hint, const KeyType &key - ,KeyNodePtrCompare comp, insert_commit_data &commit_data) - { return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); } + ,KeyNodePtrCompare comp, insert_commit_data &commit_data); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! Requires: "header" must be the header node of a tree. - //! "commit_data" must have been obtained from a previous call to - //! "insert_unique_check". No objects should have been inserted or erased - //! from the set between the "insert_unique_check" that filled "commit_data" - //! and the call to "insert_commit". - //! - //! - //! Effects: Inserts new_node in the set using the information obtained - //! from the "commit_data" that a previous "insert_check" filled. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function has only sense if a "insert_unique_check" has been - //! previously executed to fill "commit_data". No value should be inserted or - //! erased between the "insert_check" and "insert_commit" calls. + //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&) static void insert_unique_commit (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) { - tree_algorithms::insert_unique_commit(header, new_value, commit_data); + bstree_algo::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); } - //! Requires: "n" must be a node inserted in a tree. - //! - //! Effects: Returns a pointer to the header node of the tree. - //! - //! Complexity: Logarithmic. - //! - //! Throws: Nothing. - static node_ptr get_header(const node_ptr & n) - { return tree_algorithms::get_header(n); } - - /// @cond - private: - - //! Requires: p is a node of a tree. - //! - //! Effects: Returns true if p is the header of the tree. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. + //! @copydoc ::boost::intrusive::bstree_algorithms::is_header static bool is_header(const const_node_ptr & p) { return NodeTraits::get_color(p) == NodeTraits::red() && - tree_algorithms::is_header(p); - //return NodeTraits::get_color(p) == NodeTraits::red() && - // NodeTraits::get_parent(NodeTraits::get_parent(p)) == p; + bstree_algo::is_header(p); } + /// @cond + private: + static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent) { while(x != NodeTraits::get_parent(header) && (!x || NodeTraits::get_color(x) == NodeTraits::black())){ @@ -814,7 +418,7 @@ class rbtree_algorithms if(NodeTraits::get_color(w) == NodeTraits::red()){ NodeTraits::set_color(w, NodeTraits::black()); NodeTraits::set_color(x_parent, NodeTraits::red()); - tree_algorithms::rotate_left(x_parent, header); + bstree_algo::rotate_left(x_parent, header); w = NodeTraits::get_right(x_parent); } if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) && @@ -827,14 +431,14 @@ class rbtree_algorithms if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); - tree_algorithms::rotate_right(w, header); + bstree_algo::rotate_right(w, header); w = NodeTraits::get_right(x_parent); } NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); NodeTraits::set_color(x_parent, NodeTraits::black()); if(NodeTraits::get_right(w)) NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); - tree_algorithms::rotate_left(x_parent, header); + bstree_algo::rotate_left(x_parent, header); break; } } @@ -844,7 +448,7 @@ class rbtree_algorithms if(NodeTraits::get_color(w) == NodeTraits::red()){ NodeTraits::set_color(w, NodeTraits::black()); NodeTraits::set_color(x_parent, NodeTraits::red()); - tree_algorithms::rotate_right(x_parent, header); + bstree_algo::rotate_right(x_parent, header); w = NodeTraits::get_left(x_parent); } if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) && @@ -857,14 +461,14 @@ class rbtree_algorithms if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); - tree_algorithms::rotate_left(w, header); + bstree_algo::rotate_left(w, header); w = NodeTraits::get_left(x_parent); } NodeTraits::set_color(w, NodeTraits::get_color(x_parent)); NodeTraits::set_color(x_parent, NodeTraits::black()); if(NodeTraits::get_left(w)) NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); - tree_algorithms::rotate_right(x_parent, header); + bstree_algo::rotate_right(x_parent, header); break; } } @@ -873,14 +477,13 @@ class rbtree_algorithms NodeTraits::set_color(x, NodeTraits::black()); } - static void rebalance_after_insertion(const node_ptr & header, node_ptr p) { NodeTraits::set_color(p, NodeTraits::red()); while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){ node_ptr p_parent(NodeTraits::get_parent(p)); node_ptr p_parent_parent(NodeTraits::get_parent(p_parent)); - if(tree_algorithms::is_left_child(p_parent)){ + if(bstree_algo::is_left_child(p_parent)){ node_ptr x = NodeTraits::get_right(p_parent_parent); if(x && NodeTraits::get_color(x) == NodeTraits::red()){ NodeTraits::set_color(p_parent, NodeTraits::black()); @@ -889,15 +492,15 @@ class rbtree_algorithms p = p_parent_parent; } else { - if(!tree_algorithms::is_left_child(p)){ + if(!bstree_algo::is_left_child(p)){ p = p_parent; - tree_algorithms::rotate_left(p, header); + bstree_algo::rotate_left(p, header); } node_ptr new_p_parent(NodeTraits::get_parent(p)); node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); NodeTraits::set_color(new_p_parent, NodeTraits::black()); NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); - tree_algorithms::rotate_right(new_p_parent_parent, header); + bstree_algo::rotate_right(new_p_parent_parent, header); } } else{ @@ -909,15 +512,15 @@ class rbtree_algorithms p = p_parent_parent; } else{ - if(tree_algorithms::is_left_child(p)){ + if(bstree_algo::is_left_child(p)){ p = p_parent; - tree_algorithms::rotate_right(p, header); + bstree_algo::rotate_right(p, header); } node_ptr new_p_parent(NodeTraits::get_parent(p)); node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent)); NodeTraits::set_color(new_p_parent, NodeTraits::black()); NodeTraits::set_color(new_p_parent_parent, NodeTraits::red()); - tree_algorithms::rotate_left(new_p_parent_parent, header); + bstree_algo::rotate_left(new_p_parent_parent, header); } } } @@ -926,6 +529,16 @@ class rbtree_algorithms /// @endcond }; +/// @cond + +template +struct get_algo +{ + typedef rbtree_algorithms type; +}; + +/// @endcond + } //namespace intrusive } //namespace boost diff --git a/cpp/BoostParts/boost/intrusive/set.hpp b/cpp/BoostParts/boost/intrusive/set.hpp index f753a2c5..c8c197c4 100644 --- a/cpp/BoostParts/boost/intrusive/set.hpp +++ b/cpp/BoostParts/boost/intrusive/set.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -37,12 +37,15 @@ namespace intrusive { #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class set_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif { /// @cond - typedef rbtree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl) typedef tree_type implementation_defined; @@ -70,1189 +73,338 @@ class set_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; - static const bool constant_time_size = Config::constant_time_size; - //static const bool stateful_value_traits = detail::is_stateful_value_traits::value; - - /// @cond - private: - tree_type tree_; - - protected: - node &prot_header_node(){ return tree_.prot_header_node(); } - node const &prot_header_node() const{ return tree_.prot_header_node(); } - void prot_set_size(size_type s){ tree_.prot_set_size(s); } - value_compare &prot_comp(){ return tree_.prot_comp(); } - - /// @endcond + static const bool constant_time_size = tree_type::constant_time_size; public: - //! Effects: Constructs an empty set. - //! - //! Complexity: Constant. - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructor of the value_compare object throws. + //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &) explicit set_impl( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : tree_(cmp, v_traits) + : tree_type(cmp, v_traits) {} - //! Requires: Dereferencing iterator must yield an lvalue of type value_type. - //! cmp must be a comparison function that induces a strict weak ordering. - //! - //! Effects: Constructs an empty set and inserts elements from - //! [b, e). - //! - //! Complexity: Linear in N if [b, e) is already sorted using - //! comp and otherwise N * log N, where N is std::distance(last, first). - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructor/operator() of the value_compare object throws. + //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &) template set_impl( Iterator b, Iterator e , const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : tree_(true, b, e, cmp, v_traits) + : tree_type(true, b, e, cmp, v_traits) {} - //! Effects: to-do - //! + //! @copydoc ::boost::intrusive::rbtree::rbtree(rbtree &&) set_impl(BOOST_RV_REF(set_impl) x) - : tree_(::boost::move(x.tree_)) + : tree_type(::boost::move(static_cast(x))) {} - //! Effects: to-do - //! + //! @copydoc ::boost::intrusive::rbtree::operator=(rbtree &&) set_impl& operator=(BOOST_RV_REF(set_impl) x) - { tree_ = ::boost::move(x.tree_); return *this; } + { return static_cast(tree_type::operator=(::boost::move(static_cast(x)))); } - //! Effects: Detaches all elements from this. The objects in the set - //! are not deleted (i.e. no destructors are called). - //! - //! Complexity: Linear to the number of elements on the container. - //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. - //! - //! Throws: Nothing. - ~set_impl() - {} + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::rbtree::~rbtree() + ~set_impl(); - //! Effects: Returns an iterator pointing to the beginning of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator begin() - { return tree_.begin(); } + //! @copydoc ::boost::intrusive::rbtree::begin() + iterator begin(); - //! Effects: Returns a const_iterator pointing to the beginning of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator begin() const - { return tree_.begin(); } + //! @copydoc ::boost::intrusive::rbtree::begin()const + const_iterator begin() const; - //! Effects: Returns a const_iterator pointing to the beginning of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cbegin() const - { return tree_.cbegin(); } + //! @copydoc ::boost::intrusive::rbtree::cbegin()const + const_iterator cbegin() const; - //! Effects: Returns an iterator pointing to the end of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator end() - { return tree_.end(); } + //! @copydoc ::boost::intrusive::rbtree::end() + iterator end(); - //! Effects: Returns a const_iterator pointing to the end of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator end() const - { return tree_.end(); } + //! @copydoc ::boost::intrusive::rbtree::end()const + const_iterator end() const; - //! Effects: Returns a const_iterator pointing to the end of the set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cend() const - { return tree_.cend(); } + //! @copydoc ::boost::intrusive::rbtree::cend()const + const_iterator cend() const; - //! Effects: Returns a reverse_iterator pointing to the beginning of the - //! reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rbegin() - { return tree_.rbegin(); } + //! @copydoc ::boost::intrusive::rbtree::rbegin() + reverse_iterator rbegin(); - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rbegin() const - { return tree_.rbegin(); } + //! @copydoc ::boost::intrusive::rbtree::rbegin()const + const_reverse_iterator rbegin() const; - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crbegin() const - { return tree_.crbegin(); } + //! @copydoc ::boost::intrusive::rbtree::crbegin()const + const_reverse_iterator crbegin() const; - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rend() - { return tree_.rend(); } + //! @copydoc ::boost::intrusive::rbtree::rend() + reverse_iterator rend(); - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rend() const - { return tree_.rend(); } + //! @copydoc ::boost::intrusive::rbtree::rend()const + const_reverse_iterator rend() const; - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed set. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crend() const - { return tree_.crend(); } + //! @copydoc ::boost::intrusive::rbtree::crend()const + const_reverse_iterator crend() const; - //! Precondition: end_iterator must be a valid end iterator - //! of set. - //! - //! Effects: Returns a reference to the set associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static set_impl &container_from_end_iterator(iterator end_iterator) - { - return *detail::parent_from_member - ( &tree_type::container_from_end_iterator(end_iterator) - , &set_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) + static set_impl &container_from_end_iterator(iterator end_iterator); - //! Precondition: end_iterator must be a valid end const_iterator - //! of set. - //! - //! Effects: Returns a const reference to the set associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static const set_impl &container_from_end_iterator(const_iterator end_iterator) - { - return *detail::parent_from_member - ( &tree_type::container_from_end_iterator(end_iterator) - , &set_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) + static const set_impl &container_from_end_iterator(const_iterator end_iterator); - //! Precondition: it must be a valid iterator of set. - //! - //! Effects: Returns a reference to the set associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static set_impl &container_from_iterator(iterator it) - { - return *detail::parent_from_member - ( &tree_type::container_from_iterator(it) - , &set_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) + static set_impl &container_from_iterator(iterator it); - //! Precondition: it must be a valid const_iterator of set. - //! - //! Effects: Returns a const reference to the set associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static const set_impl &container_from_iterator(const_iterator it) - { - return *detail::parent_from_member - ( &tree_type::container_from_iterator(it) - , &set_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) + static const set_impl &container_from_iterator(const_iterator it); - //! Effects: Returns the key_compare object used by the set. - //! - //! Complexity: Constant. - //! - //! Throws: If key_compare copy-constructor throws. - key_compare key_comp() const - { return tree_.value_comp(); } + //! @copydoc ::boost::intrusive::rbtree::key_comp()const + key_compare key_comp() const; - //! Effects: Returns the value_compare object used by the set. - //! - //! Complexity: Constant. - //! - //! Throws: If value_compare copy-constructor throws. - value_compare value_comp() const - { return tree_.value_comp(); } + //! @copydoc ::boost::intrusive::rbtree::value_comp()const + value_compare value_comp() const; - //! Effects: Returns true if the container is empty. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - bool empty() const - { return tree_.empty(); } + //! @copydoc ::boost::intrusive::rbtree::empty()const + bool empty() const; - //! Effects: Returns the number of elements stored in the set. - //! - //! Complexity: Linear to elements contained in *this if, - //! constant-time size option is enabled. Constant-time otherwise. - //! - //! Throws: Nothing. - size_type size() const - { return tree_.size(); } + //! @copydoc ::boost::intrusive::rbtree::size()const + size_type size() const; - //! Effects: Swaps the contents of two sets. - //! - //! Complexity: Constant. - //! - //! Throws: If the swap() call for the comparison functor - //! found using ADL throws. Strong guarantee. - void swap(set_impl& other) - { tree_.swap(other.tree_); } + //! @copydoc ::boost::intrusive::rbtree::swap + void swap(set_impl& other); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! Cloner should yield to nodes equivalent to the original nodes. - //! - //! Effects: Erases all the elements from *this - //! calling Disposer::operator()(pointer), clones all the - //! elements from src calling Cloner::operator()(const_reference ) - //! and inserts them on *this. Copies the predicate from the source container. - //! - //! If cloner throws, all cloned elements are unlinked and disposed - //! calling Disposer::operator()(pointer). - //! - //! Complexity: Linear to erased plus inserted elements. - //! - //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. + //! @copydoc ::boost::intrusive::rbtree::clone_from template - void clone_from(const set_impl &src, Cloner cloner, Disposer disposer) - { tree_.clone_from(src.tree_, cloner, disposer); } + void clone_from(const set_impl &src, Cloner cloner, Disposer disposer); + + #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED - //! Requires: value must be an lvalue - //! - //! Effects: Tries to inserts value into the set. - //! - //! Returns: If the value - //! is not already present inserts it and returns a pair containing the - //! iterator to the new value and true. If there is an equivalent value - //! returns a pair containing an iterator to the already present value - //! and false. - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::rbtree::insert_unique(reference) std::pair insert(reference value) - { return tree_.insert_unique(value); } + { return tree_type::insert_unique(value); } - //! Requires: value must be an lvalue - //! - //! Effects: Tries to to insert x into the set, using "hint" - //! as a hint to where it will be inserted. - //! - //! Returns: An iterator that points to the position where the - //! new element was inserted into the set. - //! - //! Complexity: Logarithmic in general, but it's amortized - //! constant time if t is inserted immediately before hint. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::rbtree::insert_unique(const_iterator,reference) iterator insert(const_iterator hint, reference value) - { return tree_.insert_unique(hint, value); } + { return tree_type::insert_unique(hint, value); } - //! Requires: key_value_comp must be a comparison function that induces - //! the same strict weak ordering as value_compare. The difference is that - //! key_value_comp compares an arbitrary key with the contained values. - //! - //! Effects: Checks if a value can be inserted in the set, using - //! a user provided key instead of the value itself. - //! - //! Returns: If there is an equivalent value - //! returns a pair containing an iterator to the already present value - //! and false. If the value can be inserted returns true in the returned - //! pair boolean and fills "commit_data" that is meant to be used with - //! the "insert_commit" function. - //! - //! Complexity: Average complexity is at most logarithmic. - //! - //! Throws: If the key_value_comp ordering function throws. Strong guarantee. - //! - //! Notes: This function is used to improve performance when constructing - //! a value_type is expensive: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! node that is used to impose the order is much cheaper to construct - //! than the value_type and this function offers the possibility to use that - //! part to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the value_type and use - //! "insert_commit" to insert the object in constant-time. This gives a total - //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_commit" only if no more - //! objects are inserted or erased from the set. + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&) template std::pair insert_check (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) - { return tree_.insert_unique_check(key, key_value_comp, commit_data); } + { return tree_type::insert_unique_check(key, key_value_comp, commit_data); } - //! Requires: key_value_comp must be a comparison function that induces - //! the same strict weak ordering as value_compare. The difference is that - //! key_value_comp compares an arbitrary key with the contained values. - //! - //! Effects: Checks if a value can be inserted in the set, using - //! a user provided key instead of the value itself, using "hint" - //! as a hint to where it will be inserted. - //! - //! Returns: If there is an equivalent value - //! returns a pair containing an iterator to the already present value - //! and false. If the value can be inserted returns true in the returned - //! pair boolean and fills "commit_data" that is meant to be used with - //! the "insert_commit" function. - //! - //! Complexity: Logarithmic in general, but it's amortized - //! constant time if t is inserted immediately before hint. - //! - //! Throws: If the key_value_comp ordering function throws. Strong guarantee. - //! - //! Notes: This function is used to improve performance when constructing - //! a value_type is expensive: if there is an equivalent value - //! the constructed object must be discarded. Many times, the part of the - //! constructing that is used to impose the order is much cheaper to construct - //! than the value_type and this function offers the possibility to use that key - //! to check if the insertion will be successful. - //! - //! If the check is successful, the user can construct the value_type and use - //! "insert_commit" to insert the object in constant-time. This can give a total - //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). - //! - //! "commit_data" remains valid for a subsequent "insert_commit" only if no more - //! objects are inserted or erased from the set. + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&) template std::pair insert_check (const_iterator hint, const KeyType &key ,KeyValueCompare key_value_comp, insert_commit_data &commit_data) - { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); } + { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); } - //! Requires: value must be an lvalue of type value_type. commit_data - //! must have been obtained from a previous call to "insert_check". - //! No objects should have been inserted or erased from the set between - //! the "insert_check" that filled "commit_data" and the call to "insert_commit". - //! - //! Effects: Inserts the value in the set using the information obtained - //! from the "commit_data" that a previous "insert_check" filled. - //! - //! Returns: An iterator to the newly inserted object. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function has only sense if a "insert_check" has been - //! previously executed to fill "commit_data". No value should be inserted or - //! erased between the "insert_check" and "insert_commit" calls. - iterator insert_commit(reference value, const insert_commit_data &commit_data) - { return tree_.insert_unique_commit(value, commit_data); } - - //! Requires: Dereferencing iterator must yield an lvalue - //! of type value_type. - //! - //! Effects: Inserts a range into the set. - //! - //! Complexity: Insert range is in general O(N * log(N)), where N is the - //! size of the range. However, it is linear in N if the range is already sorted - //! by value_comp(). - //! - //! Throws: If the internal value_compare ordering function throws. Basic guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::rbtree::insert_unique(Iterator,Iterator) template void insert(Iterator b, Iterator e) - { tree_.insert_unique(b, e); } + { tree_type::insert_unique(b, e); } - //! Requires: value must be an lvalue, "pos" must be - //! a valid iterator (or end) and must be the succesor of value - //! once inserted according to the predicate. "value" must not be equal to any - //! inserted key according to the predicate. - //! - //! Effects: Inserts x into the tree before "pos". - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if "pos" is not - //! the successor of "value" or "value" is not unique tree ordering and uniqueness - //! invariants will be broken respectively. - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - iterator insert_before(const_iterator pos, reference value) - { return tree_.insert_before(pos, value); } + //! @copydoc ::boost::intrusive::rbtree::insert_unique_commit + iterator insert_commit(reference value, const insert_commit_data &commit_data) + { return tree_type::insert_unique_commit(value, commit_data); } - //! Requires: value must be an lvalue, and it must be greater than - //! any inserted key according to the predicate. - //! - //! Effects: Inserts x into the tree in the last position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! less than or equal to the greatest inserted key tree ordering invariant will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_back(reference value) - { tree_.push_back(value); } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::rbtree::insert_before + iterator insert_before(const_iterator pos, reference value); - //! Requires: value must be an lvalue, and it must be less - //! than any inserted key according to the predicate. - //! - //! Effects: Inserts x into the tree in the first position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! greater than or equal to the the mimum inserted key tree ordering or uniqueness - //! invariants will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_front(reference value) - { tree_.push_front(value); } + //! @copydoc ::boost::intrusive::rbtree::push_back + void push_back(reference value); - //! Effects: Erases the element pointed to by pos. - //! - //! Complexity: Average complexity is constant time. - //! - //! Returns: An iterator to the element after the erased element. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) - { return tree_.erase(i); } + //! @copydoc ::boost::intrusive::rbtree::push_front + void push_front(reference value); - //! Effects: Erases the range pointed to by b end e. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Returns: An iterator to the element after the erased elements. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) - { return tree_.erase(b, e); } + //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) + iterator erase(const_iterator i); - //! Effects: Erases all the elements with the given value. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size()) + this->count(value)). - //! - //! Throws: If the internal value_compare ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - size_type erase(const_reference value) - { return tree_.erase(value); } + //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) + iterator erase(const_iterator b, const_iterator e); - //! Effects: Erases all the elements that compare equal with - //! the given key and the given comparison functor. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(key, comp)). - //! - //! Throws: If the comp ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::rbtree::erase(const_reference) + size_type erase(const_reference value); + + //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare) template - size_type erase(const KeyType& key, KeyValueCompare comp - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { return tree_.erase(key, comp); } + size_type erase(const KeyType& key, KeyValueCompare comp); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases the element pointed to by pos. - //! Disposer::operator()(pointer) is called for the removed element. - //! - //! Complexity: Average complexity for erase element is constant time. - //! - //! Returns: An iterator to the element after the erased element. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer) - { return tree_.erase_and_dispose(i, disposer); } + iterator erase_and_dispose(const_iterator i, Disposer disposer); - #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(iterator i, Disposer disposer) - { return this->erase_and_dispose(const_iterator(i), disposer); } - #endif + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases the range pointed to by b end e. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Returns: An iterator to the element after the erased elements. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) - { return tree_.erase_and_dispose(b, e, disposer); } + size_type erase_and_dispose(const_reference value, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given value. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Throws: If the internal value_compare ordering function throws. - //! - //! Complexity: O(log(size() + this->count(value)). Basic guarantee. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - template - size_type erase_and_dispose(const_reference value, Disposer disposer) - { return tree_.erase_and_dispose(value, disposer); } - - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given key. - //! according to the comparison functor "comp". - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(key, comp)). - //! - //! Throws: If comp ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer) template - size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { return tree_.erase_and_dispose(key, comp, disposer); } + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer); - //! Effects: Erases all the elements of the container. - //! - //! Complexity: Linear to the number of elements on the container. - //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - void clear() - { return tree_.clear(); } + //! @copydoc ::boost::intrusive::rbtree::clear + void clear(); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements of the container. - //! - //! Complexity: Linear to the number of elements on the container. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer) - { return tree_.clear_and_dispose(disposer); } + void clear_and_dispose(Disposer disposer); - //! Effects: Returns the number of contained elements with the given key - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given key. - //! - //! Throws: If the internal value_compare ordering function throws. - size_type count(const_reference value) const - { return tree_.find(value) != end(); } + //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const + size_type count(const_reference value) const; - //! Effects: Returns the number of contained elements with the same key - //! compared with the given comparison functor. - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given key. - //! - //! Throws: If comp ordering function throws. + //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const template - size_type count(const KeyType& key, KeyValueCompare comp) const - { return tree_.find(key, comp) != end(); } - - //! Effects: Returns an iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator lower_bound(const_reference value) - { return tree_.lower_bound(value); } - - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns an iterator to the first element whose - //! key according to the comparison functor is not less than k or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + size_type count(const KeyType& key, KeyValueCompare comp) const; + + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference) + iterator lower_bound(const_reference value); + + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare) template - iterator lower_bound(const KeyType& key, KeyValueCompare comp) - { return tree_.lower_bound(key, comp); } + iterator lower_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns a const iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator lower_bound(const_reference value) const - { return tree_.lower_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const + const_iterator lower_bound(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns a const_iterator to the first element whose - //! key according to the comparison functor is not less than k or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const template - const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const - { return tree_.lower_bound(key, comp); } + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator upper_bound(const_reference value) - { return tree_.upper_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference) + iterator upper_bound(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns an iterator to the first element whose - //! key according to the comparison functor is greater than key or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare) template - iterator upper_bound(const KeyType& key, KeyValueCompare comp) - { return tree_.upper_bound(key, comp); } + iterator upper_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator upper_bound(const_reference value) const - { return tree_.upper_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const + const_iterator upper_bound(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns a const_iterator to the first element whose - //! key according to the comparison functor is greater than key or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const template - const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const - { return tree_.upper_bound(key, comp); } + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds an iterator to the first element whose value is - //! "value" or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator find(const_reference value) - { return tree_.find(value); } + //! @copydoc ::boost::intrusive::rbtree::find(const_reference) + iterator find(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds an iterator to the first element whose key is - //! "key" according to the comparison functor or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare) template - iterator find(const KeyType& key, KeyValueCompare comp) - { return tree_.find(key, comp); } + iterator find(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a const_iterator to the first element whose value is - //! "value" or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator find(const_reference value) const - { return tree_.find(value); } + //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const + const_iterator find(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a const_iterator to the first element whose key is - //! "key" according to the comparison functor or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const template - const_iterator find(const KeyType& key, KeyValueCompare comp) const - { return tree_.find(key, comp); } + const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - std::pair equal_range(const_reference value) - { return tree_.equal_range(value); } + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a range containing all elements whose key is k - //! according to the comparison functor or an empty range - //! that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp) - { return tree_.equal_range(key, comp); } + std::pair equal_range(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const - { return tree_.equal_range(value); } + equal_range(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a range containing all elements whose key is k - //! according to the comparison functor or an empty range - //! that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const - { return tree_.equal_range(key, comp); } + equal_range(const KeyType& key, KeyValueCompare comp) const; - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range - (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) - { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed); - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool) template std::pair bounded_range - (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) - { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed); - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const std::pair - bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const - { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const; - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const template - std::pair - bounded_range - (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const - { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const; - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static iterator s_iterator_to(reference value) - { return tree_type::s_iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) + static iterator s_iterator_to(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static const_iterator s_iterator_to(const_reference value) - { return tree_type::s_iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator iterator_to(reference value) - { return tree_.iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) + iterator iterator_to(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator iterator_to(const_reference value) const - { return tree_.iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const; - //! Requires: value shall not be in a set/multiset. - //! - //! Effects: init_node puts the hook of a value in a well-known default - //! state. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - //! - //! Note: This function puts the hook in the well-known default state - //! used by auto_unlink and safe hooks. - static void init_node(reference value) - { tree_type::init_node(value); } + //! @copydoc ::boost::intrusive::rbtree::init_node(reference) + static void init_node(reference value); - //! Effects: Unlinks the leftmost node from the tree. - //! - //! Complexity: Average complexity is constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function breaks the tree and the tree can - //! only be used for more unlink_leftmost_without_rebalance calls. - //! This function is normally used to achieve a step by step - //! controlled destruction of the tree. - pointer unlink_leftmost_without_rebalance() - { return tree_.unlink_leftmost_without_rebalance(); } + //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance + pointer unlink_leftmost_without_rebalance(); - //! Requires: replace_this must be a valid iterator of *this - //! and with_this must not be inserted in any tree. - //! - //! Effects: Replaces replace_this in its position in the - //! tree with with_this. The tree does not need to be rebalanced. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! with_this is not equivalent to *replace_this according to the - //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing or comparison is needed. - void replace_node(iterator replace_this, reference with_this) - { tree_.replace_node(replace_this, with_this); } + //! @copydoc ::boost::intrusive::rbtree::replace_node + void replace_node(iterator replace_this, reference with_this); - /// @cond - friend bool operator==(const set_impl &x, const set_impl &y) - { return x.tree_ == y.tree_; } - - friend bool operator<(const set_impl &x, const set_impl &y) - { return x.tree_ < y.tree_; } - /// @endcond + //! @copydoc ::boost::intrusive::rbtree::remove_node + void remove_node(reference value); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED }; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template -#else -template -#endif -inline bool operator!= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const set_impl &x, const set_impl &y) -#else -(const set_impl &x, const set_impl &y) -#endif -{ return !(x == y); } -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator> -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const set_impl &x, const set_impl &y) -#else -(const set_impl &x, const set_impl &y) -#endif -{ return y < x; } +bool operator!= (const set_impl &x, const set_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator<= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const set_impl &x, const set_impl &y) -#else -(const set_impl &x, const set_impl &y) -#endif -{ return !(y < x); } +bool operator>(const set_impl &x, const set_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator>= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const set_impl &x, const set_impl &y) -#else -(const set_impl &x, const set_impl &y) -#endif -{ return !(x < y); } +bool operator<=(const set_impl &x, const set_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline void swap -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(set_impl &x, set_impl &y) -#else -(set_impl &x, set_impl &y) -#endif -{ x.swap(y); } +bool operator>=(const set_impl &x, const set_impl &y); + +template +void swap(set_impl &x, set_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Helper metafunction to define a \c set that yields to the same type when the //! same options (either explicitly or implicitly) are used. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_set { /// @cond - typedef set_impl - < typename make_rbtree_opt::type - > implementation_defined; + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef set_impl + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > implementation_defined; /// @endcond typedef implementation_defined type; }; @@ -1291,8 +443,8 @@ class set //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); - set( const value_compare &cmp = value_compare() - , const value_traits &v_traits = value_traits()) + explicit set( const value_compare &cmp = value_compare() + , const value_traits &v_traits = value_traits()) : Base(cmp, v_traits) {} @@ -1308,7 +460,7 @@ class set {} set& operator=(BOOST_RV_REF(set) x) - { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + { return static_cast(this->Base::operator=(::boost::move(static_cast(x)))); } static set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1339,12 +491,15 @@ class set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class multiset_impl +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + : public bstree_impl +#endif { /// @cond - typedef rbtree_impl tree_type; + typedef bstree_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl) typedef tree_type implementation_defined; @@ -1372,1107 +527,321 @@ class multiset_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; - static const bool constant_time_size = Config::constant_time_size; - //static const bool stateful_value_traits = detail::is_stateful_value_traits::value; - - /// @cond - private: - tree_type tree_; - - protected: - node &prot_header_node(){ return tree_.prot_header_node(); } - node const &prot_header_node() const{ return tree_.prot_header_node(); } - void prot_set_size(size_type s){ tree_.prot_set_size(s); } - value_compare &prot_comp(){ return tree_.prot_comp(); } - /// @endcond + static const bool constant_time_size = tree_type::constant_time_size; public: - //! Effects: Constructs an empty multiset. - //! - //! Complexity: Constant. - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructor/operator() of the value_compare object throws. + //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &) explicit multiset_impl( const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : tree_(cmp, v_traits) + : tree_type(cmp, v_traits) {} - //! Requires: Dereferencing iterator must yield an lvalue of type value_type. - //! cmp must be a comparison function that induces a strict weak ordering. - //! - //! Effects: Constructs an empty multiset and inserts elements from - //! [b, e). - //! - //! Complexity: Linear in N if [b, e) is already sorted using - //! comp and otherwise N * log N, where N is the distance between first and last - //! - //! Throws: If value_traits::node_traits::node - //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) - //! or the copy constructor/operator() of the value_compare object throws. + //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &) template multiset_impl( Iterator b, Iterator e , const value_compare &cmp = value_compare() , const value_traits &v_traits = value_traits()) - : tree_(false, b, e, cmp, v_traits) + : tree_type(false, b, e, cmp, v_traits) {} - //! Effects: to-do - //! + //! @copydoc ::boost::intrusive::rbtree::rbtree(rbtree &&) multiset_impl(BOOST_RV_REF(multiset_impl) x) - : tree_(::boost::move(x.tree_)) + : tree_type(::boost::move(static_cast(x))) {} - //! Effects: to-do - //! + //! @copydoc ::boost::intrusive::rbtree::operator=(rbtree &&) multiset_impl& operator=(BOOST_RV_REF(multiset_impl) x) - { tree_ = ::boost::move(x.tree_); return *this; } + { return static_cast(tree_type::operator=(::boost::move(static_cast(x)))); } - //! Effects: Detaches all elements from this. The objects in the set - //! are not deleted (i.e. no destructors are called). - //! - //! Complexity: Linear to the number of elements on the container. - //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. - //! - //! Throws: Nothing. - ~multiset_impl() - {} + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::rbtree::~rbtree() + ~multiset_impl(); - //! Effects: Returns an iterator pointing to the beginning of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator begin() - { return tree_.begin(); } + //! @copydoc ::boost::intrusive::rbtree::begin() + iterator begin(); - //! Effects: Returns a const_iterator pointing to the beginning of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator begin() const - { return tree_.begin(); } + //! @copydoc ::boost::intrusive::rbtree::begin()const + const_iterator begin() const; - //! Effects: Returns a const_iterator pointing to the beginning of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cbegin() const - { return tree_.cbegin(); } + //! @copydoc ::boost::intrusive::rbtree::cbegin()const + const_iterator cbegin() const; - //! Effects: Returns an iterator pointing to the end of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator end() - { return tree_.end(); } + //! @copydoc ::boost::intrusive::rbtree::end() + iterator end(); - //! Effects: Returns a const_iterator pointing to the end of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator end() const - { return tree_.end(); } + //! @copydoc ::boost::intrusive::rbtree::end()const + const_iterator end() const; - //! Effects: Returns a const_iterator pointing to the end of the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator cend() const - { return tree_.cend(); } + //! @copydoc ::boost::intrusive::rbtree::cend()const + const_iterator cend() const; - //! Effects: Returns a reverse_iterator pointing to the beginning of the - //! reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rbegin() - { return tree_.rbegin(); } + //! @copydoc ::boost::intrusive::rbtree::rbegin() + reverse_iterator rbegin(); - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rbegin() const - { return tree_.rbegin(); } + //! @copydoc ::boost::intrusive::rbtree::rbegin()const + const_reverse_iterator rbegin() const; - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crbegin() const - { return tree_.crbegin(); } + //! @copydoc ::boost::intrusive::rbtree::crbegin()const + const_reverse_iterator crbegin() const; - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - reverse_iterator rend() - { return tree_.rend(); } + //! @copydoc ::boost::intrusive::rbtree::rend() + reverse_iterator rend(); - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator rend() const - { return tree_.rend(); } + //! @copydoc ::boost::intrusive::rbtree::rend()const + const_reverse_iterator rend() const; - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed multiset. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_reverse_iterator crend() const - { return tree_.crend(); } + //! @copydoc ::boost::intrusive::rbtree::crend()const + const_reverse_iterator crend() const; - //! Precondition: end_iterator must be a valid end iterator - //! of multiset. - //! - //! Effects: Returns a const reference to the multiset associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static multiset_impl &container_from_end_iterator(iterator end_iterator) - { - return *detail::parent_from_member - ( &tree_type::container_from_end_iterator(end_iterator) - , &multiset_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator) + static multiset_impl &container_from_end_iterator(iterator end_iterator); - //! Precondition: end_iterator must be a valid end const_iterator - //! of multiset. - //! - //! Effects: Returns a const reference to the multiset associated to the end iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - static const multiset_impl &container_from_end_iterator(const_iterator end_iterator) - { - return *detail::parent_from_member - ( &tree_type::container_from_end_iterator(end_iterator) - , &multiset_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator) + static const multiset_impl &container_from_end_iterator(const_iterator end_iterator); - //! Precondition: it must be a valid iterator of multiset. - //! - //! Effects: Returns a const reference to the multiset associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static multiset_impl &container_from_iterator(iterator it) - { - return *detail::parent_from_member - ( &tree_type::container_from_iterator(it) - , &multiset_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator) + static multiset_impl &container_from_iterator(iterator it); - //! Precondition: it must be a valid const_iterator of multiset. - //! - //! Effects: Returns a const reference to the multiset associated to the iterator - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic. - static const multiset_impl &container_from_iterator(const_iterator it) - { - return *detail::parent_from_member - ( &tree_type::container_from_iterator(it) - , &multiset_impl::tree_); - } + //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator) + static const multiset_impl &container_from_iterator(const_iterator it); - //! Effects: Returns the key_compare object used by the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: If key_compare copy-constructor throws. - key_compare key_comp() const - { return tree_.value_comp(); } + //! @copydoc ::boost::intrusive::rbtree::key_comp()const + key_compare key_comp() const; - //! Effects: Returns the value_compare object used by the multiset. - //! - //! Complexity: Constant. - //! - //! Throws: If value_compare copy-constructor throws. - value_compare value_comp() const - { return tree_.value_comp(); } + //! @copydoc ::boost::intrusive::rbtree::value_comp()const + value_compare value_comp() const; - //! Effects: Returns true if the container is empty. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - bool empty() const - { return tree_.empty(); } + //! @copydoc ::boost::intrusive::rbtree::empty()const + bool empty() const; - //! Effects: Returns the number of elements stored in the multiset. - //! - //! Complexity: Linear to elements contained in *this if, - //! constant-time size option is enabled. Constant-time otherwise. - //! - //! Throws: Nothing. - size_type size() const - { return tree_.size(); } + //! @copydoc ::boost::intrusive::rbtree::size()const + size_type size() const; - //! Effects: Swaps the contents of two multisets. - //! - //! Complexity: Constant. - //! - //! Throws: If the swap() call for the comparison functor - //! found using ADL throws. Strong guarantee. - void swap(multiset_impl& other) - { tree_.swap(other.tree_); } + //! @copydoc ::boost::intrusive::rbtree::swap + void swap(multiset_impl& other); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! Cloner should yield to nodes equivalent to the original nodes. - //! - //! Effects: Erases all the elements from *this - //! calling Disposer::operator()(pointer), clones all the - //! elements from src calling Cloner::operator()(const_reference ) - //! and inserts them on *this. Copies the predicate from the source container. - //! - //! If cloner throws, all cloned elements are unlinked and disposed - //! calling Disposer::operator()(pointer). - //! - //! Complexity: Linear to erased plus inserted elements. - //! - //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee. + //! @copydoc ::boost::intrusive::rbtree::clone_from template - void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer) - { tree_.clone_from(src.tree_, cloner, disposer); } + void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer); - //! Requires: value must be an lvalue - //! - //! Effects: Inserts value into the multiset. - //! - //! Returns: An iterator that points to the position where the new - //! element was inserted. - //! - //! Complexity: Average complexity for insert element is at - //! most logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED + + //! @copydoc ::boost::intrusive::rbtree::insert_equal(reference) iterator insert(reference value) - { return tree_.insert_equal(value); } + { return tree_type::insert_equal(value); } - //! Requires: value must be an lvalue - //! - //! Effects: Inserts x into the multiset, using pos as a hint to - //! where it will be inserted. - //! - //! Returns: An iterator that points to the position where the new - //! element was inserted. - //! - //! Complexity: Logarithmic in general, but it is amortized - //! constant time if t is inserted immediately before hint. - //! - //! Throws: If the internal value_compare ordering function throws. Strong guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::rbtree::insert_equal(const_iterator,reference) iterator insert(const_iterator hint, reference value) - { return tree_.insert_equal(hint, value); } + { return tree_type::insert_equal(hint, value); } - //! Requires: Dereferencing iterator must yield an lvalue - //! of type value_type. - //! - //! Effects: Inserts a range into the multiset. - //! - //! Returns: An iterator that points to the position where the new - //! element was inserted. - //! - //! Complexity: Insert range is in general O(N * log(N)), where N is the - //! size of the range. However, it is linear in N if the range is already sorted - //! by value_comp(). - //! - //! Throws: If the internal value_compare ordering function throws. Basic guarantee. - //! - //! Note: Does not affect the validity of iterators and references. - //! No copy-constructors are called. + //! @copydoc ::boost::intrusive::rbtree::insert_equal(Iterator,Iterator) template void insert(Iterator b, Iterator e) - { tree_.insert_equal(b, e); } + { tree_type::insert_equal(b, e); } - //! Requires: value must be an lvalue, "pos" must be - //! a valid iterator (or end) and must be the succesor of value - //! once inserted according to the predicate - //! - //! Effects: Inserts x into the tree before "pos". - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if "pos" is not - //! the successor of "value" tree ordering invariant will be broken. - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - iterator insert_before(const_iterator pos, reference value) - { return tree_.insert_before(pos, value); } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::rbtree::insert_before + iterator insert_before(const_iterator pos, reference value); - //! Requires: value must be an lvalue, and it must be no less - //! than the greatest inserted key - //! - //! Effects: Inserts x into the tree in the last position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! less than the greatest inserted key tree ordering invariant will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_back(reference value) - { tree_.push_back(value); } + //! @copydoc ::boost::intrusive::rbtree::push_back + void push_back(reference value); - //! Requires: value must be an lvalue, and it must be no greater - //! than the minimum inserted key - //! - //! Effects: Inserts x into the tree in the first position. - //! - //! Complexity: Constant time. - //! - //! Throws: Nothing. - //! - //! Note: This function does not check preconditions so if value is - //! greater than the minimum inserted key tree ordering invariant will be broken. - //! This function is slightly more efficient than using "insert_before". - //! This is a low-level function to be used only for performance reasons - //! by advanced users. - void push_front(reference value) - { tree_.push_front(value); } + //! @copydoc ::boost::intrusive::rbtree::push_front + void push_front(reference value); - //! Effects: Erases the element pointed to by pos. - //! - //! Complexity: Average complexity is constant time. - //! - //! Returns: An iterator to the element after the erased element. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator i) - { return tree_.erase(i); } + //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator) + iterator erase(const_iterator i); - //! Effects: Erases the range pointed to by b end e. - //! - //! Returns: An iterator to the element after the erased elements. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, iterator e) - { return tree_.erase(b, e); } + //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator) + iterator erase(const_iterator b, const_iterator e); - //! Effects: Erases all the elements with the given value. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(value)). - //! - //! Throws: If the internal value_compare ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - size_type erase(const_reference value) - { return tree_.erase(value); } + //! @copydoc ::boost::intrusive::rbtree::erase(const_reference) + size_type erase(const_reference value); - //! Effects: Erases all the elements that compare equal with - //! the given key and the given comparison functor. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(key, comp)). - //! - //! Throws: If comp ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare) template - size_type erase(const KeyType& key, KeyValueCompare comp - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { return tree_.erase(key, comp); } + size_type erase(const KeyType& key, KeyValueCompare comp); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Returns: An iterator to the element after the erased element. - //! - //! Effects: Erases the element pointed to by pos. - //! Disposer::operator()(pointer) is called for the removed element. - //! - //! Complexity: Average complexity for erase element is constant time. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer) template - iterator erase_and_dispose(const_iterator i, Disposer disposer) - { return tree_.erase_and_dispose(i, disposer); } + iterator erase_and_dispose(const_iterator i, Disposer disposer); - #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer) template - iterator erase_and_dispose(iterator i, Disposer disposer) - { return this->erase_and_dispose(const_iterator(i), disposer); } - #endif + iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Returns: An iterator to the element after the erased elements. - //! - //! Effects: Erases the range pointed to by b end e. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Complexity: Average complexity for erase range is at most - //! O(log(size() + N)), where N is the number of elements in the range. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer) template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) - { return tree_.erase_and_dispose(b, e, disposer); } + size_type erase_and_dispose(const_reference value, Disposer disposer); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given value. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(value)). - //! - //! Throws: If the internal value_compare ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - template - size_type erase_and_dispose(const_reference value, Disposer disposer) - { return tree_.erase_and_dispose(value, disposer); } - - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements with the given key. - //! according to the comparison functor "comp". - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Returns: The number of erased elements. - //! - //! Complexity: O(log(size() + this->count(key, comp)). - //! - //! Throws: If comp ordering function throws. Basic guarantee. - //! - //! Note: Invalidates the iterators - //! to the erased elements. + //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer) template - size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer - /// @cond - , typename detail::enable_if_c::value >::type * = 0 - /// @endcond - ) - { return tree_.erase_and_dispose(key, comp, disposer); } + size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer); - //! Effects: Erases all the elements of the container. - //! - //! Complexity: Linear to the number of elements on the container. - //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. - void clear() - { return tree_.clear(); } + //! @copydoc ::boost::intrusive::rbtree::clear + void clear(); - //! Requires: Disposer::operator()(pointer) shouldn't throw. - //! - //! Effects: Erases all the elements of the container. - //! - //! Complexity: Linear to the number of elements on the container. - //! Disposer::operator()(pointer) is called for the removed elements. - //! - //! Throws: Nothing. - //! - //! Note: Invalidates the iterators (but not the references) - //! to the erased elements. No destructors are called. + //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose template - void clear_and_dispose(Disposer disposer) - { return tree_.clear_and_dispose(disposer); } + void clear_and_dispose(Disposer disposer); - //! Effects: Returns the number of contained elements with the given key - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given key. - //! - //! Throws: If the internal value_compare ordering function throws. - size_type count(const_reference value) const - { return tree_.count(value); } + //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const + size_type count(const_reference value) const; - //! Effects: Returns the number of contained elements with the same key - //! compared with the given comparison functor. - //! - //! Complexity: Logarithmic to the number of elements contained plus lineal - //! to number of objects with the given key. - //! - //! Throws: If comp ordering function throws. + //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const template - size_type count(const KeyType& key, KeyValueCompare comp) const - { return tree_.count(key, comp); } - - //! Effects: Returns an iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator lower_bound(const_reference value) - { return tree_.lower_bound(value); } - - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns an iterator to the first element whose - //! key according to the comparison functor is not less than k or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + size_type count(const KeyType& key, KeyValueCompare comp) const; + + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference) + iterator lower_bound(const_reference value); + + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare) template - iterator lower_bound(const KeyType& key, KeyValueCompare comp) - { return tree_.lower_bound(key, comp); } + iterator lower_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns a const iterator to the first element whose - //! key is not less than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator lower_bound(const_reference value) const - { return tree_.lower_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const + const_iterator lower_bound(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns a const_iterator to the first element whose - //! key according to the comparison functor is not less than k or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const template - const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const - { return tree_.lower_bound(key, comp); } + const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator upper_bound(const_reference value) - { return tree_.upper_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference) + iterator upper_bound(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns an iterator to the first element whose - //! key according to the comparison functor is greater than key or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare) template - iterator upper_bound(const KeyType& key, KeyValueCompare comp) - { return tree_.upper_bound(key, comp); } + iterator upper_bound(const KeyType& key, KeyValueCompare comp); - //! Effects: Returns an iterator to the first element whose - //! key is greater than k or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator upper_bound(const_reference value) const - { return tree_.upper_bound(value); } + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const + const_iterator upper_bound(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Returns a const_iterator to the first element whose - //! key according to the comparison functor is greater than key or - //! end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const template - const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const - { return tree_.upper_bound(key, comp); } + const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds an iterator to the first element whose value is - //! "value" or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - iterator find(const_reference value) - { return tree_.find(value); } + //! @copydoc ::boost::intrusive::rbtree::find(const_reference) + iterator find(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds an iterator to the first element whose key is - //! "key" according to the comparison functor or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare) template - iterator find(const KeyType& key, KeyValueCompare comp) - { return tree_.find(key, comp); } + iterator find(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a const_iterator to the first element whose value is - //! "value" or end() if that element does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - const_iterator find(const_reference value) const - { return tree_.find(value); } + //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const + const_iterator find(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a const_iterator to the first element whose key is - //! "key" according to the comparison functor or end() if that element - //! does not exist. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const template - const_iterator find(const KeyType& key, KeyValueCompare comp) const - { return tree_.find(key, comp); } + const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. - std::pair equal_range(const_reference value) - { return tree_.equal_range(value); } + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value); - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a range containing all elements whose key is k - //! according to the comparison functor or an empty range - //! that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp) - { return tree_.equal_range(key, comp); } + std::pair equal_range(const KeyType& key, KeyValueCompare comp); - //! Effects: Finds a range containing all elements whose key is k or - //! an empty range that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the internal value_compare ordering function throws. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const - { return tree_.equal_range(value); } + equal_range(const_reference value) const; - //! Requires: comp must imply the same element order as - //! value_compare. Usually key is the part of the value_type - //! that is used in the ordering functor. - //! - //! Effects: Finds a range containing all elements whose key is k - //! according to the comparison functor or an empty range - //! that indicates the position where those elements would be - //! if they there is no elements with key k. - //! - //! Complexity: Logarithmic. - //! - //! Throws: If comp ordering function throws. - //! - //! Note: This function is used when constructing a value_type - //! is expensive and the value_type can be compared with a cheaper - //! key type. Usually this key is part of the value_type. + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const - { return tree_.equal_range(key, comp); } + equal_range(const KeyType& key, KeyValueCompare comp) const; - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range - (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) - { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed); - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool) template std::pair bounded_range - (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) - { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed); - //! Requires: 'lower_value' must not be greater than 'upper_value'. If - //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise - //! - //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If the predicate throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_value and upper_value. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const std::pair - bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const - { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const; - //! Requires: KeyValueCompare is a function object that induces a strict weak - //! ordering compatible with the strict weak ordering used to create the - //! the tree. - //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If - //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. - //! - //! Effects: Returns an a pair with the following criteria: - //! - //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise - //! - //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise - //! - //! Complexity: Logarithmic. - //! - //! Throws: If "comp" throws. - //! - //! Note: This function can be more efficient than calling upper_bound - //! and lower_bound for lower_key and upper_key. + //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const template - std::pair - bounded_range - (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const - { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const; - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static iterator s_iterator_to(reference value) - { return tree_type::s_iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference) + static iterator s_iterator_to(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This static function is available only if the value traits - //! is stateless. - static const_iterator s_iterator_to(const_reference value) - { return tree_type::s_iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference) + static const_iterator s_iterator_to(const_reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid iterator i belonging to the set - //! that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - iterator iterator_to(reference value) - { return tree_.iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference) + iterator iterator_to(reference value); - //! Requires: value must be an lvalue and shall be in a set of - //! appropriate type. Otherwise the behavior is undefined. - //! - //! Effects: Returns: a valid const_iterator i belonging to the - //! set that points to the value - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - const_iterator iterator_to(const_reference value) const - { return tree_.iterator_to(value); } + //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const + const_iterator iterator_to(const_reference value) const; - //! Requires: value shall not be in a set/multiset. - //! - //! Effects: init_node puts the hook of a value in a well-known default - //! state. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant time. - //! - //! Note: This function puts the hook in the well-known default state - //! used by auto_unlink and safe hooks. - static void init_node(reference value) - { tree_type::init_node(value); } + //! @copydoc ::boost::intrusive::rbtree::init_node(reference) + static void init_node(reference value); - //! Effects: Unlinks the leftmost node from the tree. - //! - //! Complexity: Average complexity is constant time. - //! - //! Throws: Nothing. - //! - //! Notes: This function breaks the tree and the tree can - //! only be used for more unlink_leftmost_without_rebalance calls. - //! This function is normally used to achieve a step by step - //! controlled destruction of the tree. - pointer unlink_leftmost_without_rebalance() - { return tree_.unlink_leftmost_without_rebalance(); } + //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance + pointer unlink_leftmost_without_rebalance(); - //! Requires: replace_this must be a valid iterator of *this - //! and with_this must not be inserted in any tree. - //! - //! Effects: Replaces replace_this in its position in the - //! tree with with_this. The tree does not need to be rebalanced. - //! - //! Complexity: Constant. - //! - //! Throws: Nothing. - //! - //! Note: This function will break container ordering invariants if - //! with_this is not equivalent to *replace_this according to the - //! ordering rules. This function is faster than erasing and inserting - //! the node, since no rebalancing or comparison is needed. - void replace_node(iterator replace_this, reference with_this) - { tree_.replace_node(replace_this, with_this); } + //! @copydoc ::boost::intrusive::rbtree::replace_node + void replace_node(iterator replace_this, reference with_this); - //! Effects: removes "value" from the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Logarithmic time. - //! - //! Note: This static function is only usable with non-constant - //! time size containers that have stateless comparison functors. - //! - //! If the user calls - //! this function with a constant time size container or stateful comparison - //! functor a compilation error will be issued. - static void remove_node(reference value) - { tree_type::remove_node(value); } - - /// @cond - friend bool operator==(const multiset_impl &x, const multiset_impl &y) - { return x.tree_ == y.tree_; } - - friend bool operator<(const multiset_impl &x, const multiset_impl &y) - { return x.tree_ < y.tree_; } - /// @endcond + //! @copydoc ::boost::intrusive::rbtree::remove_node + void remove_node(reference value); + #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED }; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template -#else -template -#endif -inline bool operator!= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const multiset_impl &x, const multiset_impl &y) -#else -(const multiset_impl &x, const multiset_impl &y) -#endif -{ return !(x == y); } -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator> -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const multiset_impl &x, const multiset_impl &y) -#else -(const multiset_impl &x, const multiset_impl &y) -#endif -{ return y < x; } +bool operator!= (const multiset_impl &x, const multiset_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator<= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const multiset_impl &x, const multiset_impl &y) -#else -(const multiset_impl &x, const multiset_impl &y) -#endif -{ return !(y < x); } +bool operator>(const multiset_impl &x, const multiset_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline bool operator>= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const multiset_impl &x, const multiset_impl &y) -#else -(const multiset_impl &x, const multiset_impl &y) -#endif -{ return !(x < y); } +bool operator<=(const multiset_impl &x, const multiset_impl &y); -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template -#else -template -#endif -inline void swap -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(multiset_impl &x, multiset_impl &y) -#else -(multiset_impl &x, multiset_impl &y) -#endif -{ x.swap(y); } +bool operator>=(const multiset_impl &x, const multiset_impl &y); + +template +void swap(multiset_impl &x, multiset_impl &y); + +#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) //! Helper metafunction to define a \c multiset that yields to the same type when the //! same options (either explicitly or implicitly) are used. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_multiset { /// @cond - typedef multiset_impl - < typename make_rbtree_opt::type - > implementation_defined; + >::type packed_options; + + typedef typename detail::get_value_traits + ::type value_traits; + + typedef multiset_impl + < value_traits + , typename packed_options::compare + , typename packed_options::size_type + , packed_options::constant_time_size + > implementation_defined; /// @endcond typedef implementation_defined type; }; @@ -2529,7 +898,7 @@ class multiset {} multiset& operator=(BOOST_RV_REF(multiset) x) - { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + { return static_cast(this->Base::operator=(::boost::move(static_cast(x)))); } static multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/cpp/BoostParts/boost/intrusive/set_hook.hpp b/cpp/BoostParts/boost/intrusive/set_hook.hpp index 2634b42e..38da7bcd 100644 --- a/cpp/BoostParts/boost/intrusive/set_hook.hpp +++ b/cpp/BoostParts/boost/intrusive/set_hook.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -38,7 +38,7 @@ struct get_set_node_algo #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_set_base_hook { @@ -52,12 +52,12 @@ struct make_set_base_hook #endif >::type packed_options; - typedef detail::generic_hook + typedef generic_hook < get_set_node_algo , typename packed_options::tag , packed_options::link_mode - , detail::SetBaseHook + , RbTreeBaseHookId > implementation_defined; /// @endcond typedef implementation_defined type; @@ -170,7 +170,7 @@ class set_base_hook #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_set_member_hook { @@ -184,12 +184,12 @@ struct make_set_member_hook #endif >::type packed_options; - typedef detail::generic_hook + typedef generic_hook < get_set_node_algo , member_tag , packed_options::link_mode - , detail::NoBaseHook + , NoBaseHookId > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/cpp/BoostParts/boost/intrusive/slist.hpp b/cpp/BoostParts/boost/intrusive/slist.hpp index bee6ac70..c4718264 100644 --- a/cpp/BoostParts/boost/intrusive/slist.hpp +++ b/cpp/BoostParts/boost/intrusive/slist.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -38,16 +38,6 @@ namespace intrusive { /// @cond -template -struct slistopt -{ - typedef ValueTraits value_traits; - typedef SizeType size_type; - static const bool constant_time_size = ConstantTimeSize; - static const bool linear = Linear; - static const bool cache_last = CacheLast; -}; - template struct root_plus_last { @@ -61,17 +51,22 @@ struct root_plus_last Node root_; }; -template struct slist_defaults - : pack_options - < none - , base_hook - , constant_time_size - , linear - , size_type - , cache_last - >::type -{}; +{ + typedef detail::default_slist_hook proto_value_traits; + static const bool constant_time_size = true; + static const bool linear = false; + typedef std::size_t size_type; + static const bool cache_last = false; +}; + +struct slist_bool_flags +{ + static const std::size_t linear_pos = 1u; + static const std::size_t constant_time_size_pos = 2u; + static const std::size_t cache_last_pos = 4u; +}; + /// @endcond @@ -101,23 +96,22 @@ struct slist_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class slist_impl - : private detail::clear_on_destructor_base > + : private detail::clear_on_destructor_base + < slist_impl + , is_safe_autounlink::type::link_mode>::value + > { - template friend class detail::clear_on_destructor_base; + template friend class detail::clear_on_destructor_base; //Public typedefs public: - typedef typename Config::value_traits value_traits; + typedef ValueTraits value_traits; /// @cond static const bool external_value_traits = detail::external_value_traits_bool_is_true::value; - typedef typename detail::eval_if_c - < external_value_traits - , detail::eval_value_traits - , detail::identity - >::type real_value_traits; + typedef typename detail::get_real_value_traits::type real_value_traits; /// @endcond typedef typename real_value_traits::pointer pointer; typedef typename real_value_traits::const_pointer const_pointer; @@ -125,25 +119,25 @@ class slist_impl typedef typename pointer_traits::reference reference; typedef typename pointer_traits::reference const_reference; typedef typename pointer_traits::difference_type difference_type; - typedef typename Config::size_type size_type; - typedef slist_iterator iterator; - typedef slist_iterator const_iterator; + typedef SizeType size_type; + typedef slist_iterator iterator; + typedef slist_iterator const_iterator; typedef typename real_value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; + static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos); + static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos); + static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos); + typedef typename detail::if_c - < Config::linear + < linear , linear_slist_algorithms , circular_slist_algorithms >::type node_algorithms; - static const bool constant_time_size = Config::constant_time_size; - static const bool stateful_value_traits = detail::is_stateful_value_traits::value; - static const bool linear = Config::linear; - static const bool cache_last = Config::cache_last; - /// @cond private: typedef detail::size_holder size_traits; @@ -151,9 +145,7 @@ class slist_impl //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl) - enum { safemode_or_autounlink = - (int)real_value_traits::link_mode == (int)auto_unlink || - (int)real_value_traits::link_mode == (int)safe_link }; + static const bool safemode_or_autounlink = is_safe_autounlink::value; //Constant-time size is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); @@ -207,9 +199,6 @@ class slist_impl void set_last_node(const node_ptr & n, detail::bool_) { data_.root_plus_size_.last_ = n; } - static node_ptr uncast(const const_node_ptr & ptr) - { return pointer_traits::const_cast_from(ptr); } - void set_default_constructed_state() { node_algorithms::init_header(this->get_root_node()); @@ -228,7 +217,7 @@ class slist_impl : public slist_impl::value_traits { typedef typename slist_impl::value_traits value_traits; - data_t(const value_traits &val_traits) + explicit data_t(const value_traits &val_traits) : value_traits(val_traits) {} @@ -279,6 +268,11 @@ class slist_impl real_value_traits &get_real_value_traits() { return this->get_real_value_traits(detail::bool_()); } + typedef typename pointer_traits::template rebind_pointer::type const_real_value_traits_ptr; + + const_real_value_traits_ptr real_value_traits_ptr() const + { return pointer_traits::pointer_to(this->get_real_value_traits()); } + public: ///@cond @@ -358,6 +352,7 @@ class slist_impl slist_impl& operator=(BOOST_RV_REF(slist_impl) x) { this->swap(x); return *this; } + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! Effects: If it's a safe-mode //! or auto-unlink value, the destructor does nothing //! (ie. no code is generated). Otherwise it detaches all elements from this. @@ -369,6 +364,7 @@ class slist_impl //! it's a safe-mode or auto-unlink value. Otherwise constant. ~slist_impl() {} + #endif //! Effects: Erases all the elements of the container. //! @@ -511,7 +507,7 @@ class slist_impl //! //! Complexity: Constant. const_reference front() const - { return *this->get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); } + { return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } //! Effects: Returns a reference to the last element of the list. //! @@ -547,7 +543,7 @@ class slist_impl //! //! Complexity: Constant. iterator begin() - { return iterator (node_traits::get_next(this->get_root_node()), this); } + { return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. //! @@ -555,7 +551,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator begin() const - { return const_iterator (node_traits::get_next(this->get_root_node()), this); } + { return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the first element contained in the list. //! @@ -563,7 +559,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator cbegin() const - { return const_iterator(node_traits::get_next(this->get_root_node()), this); } + { return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } //! Effects: Returns an iterator to the end of the list. //! @@ -571,7 +567,7 @@ class slist_impl //! //! Complexity: Constant. iterator end() - { return iterator(this->get_end_node(), this); } + { return iterator(this->get_end_node(), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. //! @@ -579,7 +575,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator end() const - { return const_iterator(uncast(this->get_end_node()), this); } + { return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the end of the list. //! @@ -596,7 +592,7 @@ class slist_impl //! //! Complexity: Constant. iterator before_begin() - { return iterator(this->get_root_node(), this); } + { return iterator(this->get_root_node(), this->real_value_traits_ptr()); } //! Effects: Returns an iterator that points to a position //! before the first element. Equivalent to "end()" @@ -605,7 +601,7 @@ class slist_impl //! //! Complexity: Constant. const_iterator before_begin() const - { return const_iterator(uncast(this->get_root_node()), this); } + { return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); } //! Effects: Returns an iterator that points to a position //! before the first element. Equivalent to "end()" @@ -627,7 +623,7 @@ class slist_impl { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); - return iterator (this->get_last_node(), this); + return iterator (this->get_last_node(), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the last element contained in the list. @@ -641,7 +637,7 @@ class slist_impl { //This function shall not be used if cache_last is not true BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); - return const_iterator (this->get_last_node(), this); + return const_iterator (this->get_last_node(), this->real_value_traits_ptr()); } //! Effects: Returns a const_iterator to the last element contained in the list. @@ -652,7 +648,7 @@ class slist_impl //! //! Note: This function is present only if cached_last<> option is true. const_iterator clast() const - { return const_iterator(this->get_last_node(), this); } + { return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); } //! Precondition: end_iterator must be a valid end iterator //! of slist. @@ -801,7 +797,7 @@ class slist_impl this->set_last_node(n); } this->priv_size_traits().increment(); - return iterator (n, this); + return iterator (n, this->real_value_traits_ptr()); } //! Requires: Dereferencing iterator must yield @@ -1696,7 +1692,7 @@ class slist_impl { BOOST_STATIC_ASSERT((!stateful_value_traits)); //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); - return iterator (value_traits::to_node_ptr(value), 0); + return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1714,7 +1710,7 @@ class slist_impl { BOOST_STATIC_ASSERT((!stateful_value_traits)); //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), const_real_value_traits_ptr()); } //! Requires: value must be a reference to a value inserted in a list. @@ -1729,7 +1725,7 @@ class slist_impl iterator iterator_to(reference value) { //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); - return iterator (value_traits::to_node_ptr(value), this); + return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); } //! Requires: value must be a const reference to a value inserted in a list. @@ -1744,7 +1740,7 @@ class slist_impl const_iterator iterator_to(const_reference value) const { //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast (value)))); - return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); + return const_iterator (value_traits::to_node_ptr(const_cast (value)), this->real_value_traits_ptr()); } //! Returns: The iterator to the element before i in the list. @@ -1793,11 +1789,11 @@ class slist_impl const_iterator previous(const_iterator prev_from, const_iterator i) const { if(cache_last && (i.pointed_node() == this->get_end_node())){ - return const_iterator(uncast(this->get_last_node()), this); + return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr()); } return const_iterator (node_algorithms::get_previous_node - (prev_from.pointed_node(), i.pointed_node()), this); + (prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr()); } ///@cond @@ -1846,7 +1842,11 @@ class slist_impl { if(n){ BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); - BOOST_INTRUSIVE_INVARIANT_ASSERT(size_type(std::distance(iterator(f, this), iterator(before_l, this)))+1 == n); + BOOST_INTRUSIVE_INVARIANT_ASSERT + (size_type(std::distance + ( iterator(f, this->real_value_traits_ptr()) + , iterator(before_l, this->real_value_traits_ptr()))) + +1 == n); this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); if(constant_time_size){ this->priv_size_traits().increase(n); @@ -1994,29 +1994,31 @@ class slist_impl #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator< #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { - typedef slist_impl slist_type; + typedef slist_impl slist_type; typedef typename slist_type::const_iterator const_iterator; const bool C = slist_type::constant_time_size; if(C && x.size() != y.size()){ @@ -2046,65 +2048,70 @@ bool operator== #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator!= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(x == y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator> #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return y < x; } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator<= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(y < x); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline bool operator>= #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (const slist_impl &x, const slist_impl &y) #else -(const slist_impl &x, const slist_impl &y) +( const slist_impl &x +, const slist_impl &y) #endif { return !(x < y); } #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) (slist_impl &x, slist_impl &y) #else -(slist_impl &x, slist_impl &y) +( slist_impl &x +, slist_impl &y) #endif { x.swap(y); } @@ -2113,13 +2120,13 @@ inline void swap #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_slist { /// @cond typedef typename pack_options - < slist_defaults, + < slist_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) O1, O2, O3, O4, O5 #else @@ -2127,16 +2134,13 @@ struct make_slist #endif >::type packed_options; typedef typename detail::get_value_traits - ::type value_traits; + ::type value_traits; typedef slist_impl - < - slistopt - < value_traits - , typename packed_options::size_type - , packed_options::constant_time_size - , packed_options::linear - , packed_options::cache_last - > + < value_traits + , typename packed_options::size_type + , (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos) + |(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos) + |(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos) > implementation_defined; /// @endcond typedef implementation_defined type; @@ -2200,7 +2204,7 @@ class slist {} slist& operator=(BOOST_RV_REF(slist) x) - { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + { return static_cast(this->Base::operator=(::boost::move(static_cast(x)))); } static slist &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/cpp/BoostParts/boost/intrusive/slist_hook.hpp b/cpp/BoostParts/boost/intrusive/slist_hook.hpp index cd94a7e7..fc160d9f 100644 --- a/cpp/BoostParts/boost/intrusive/slist_hook.hpp +++ b/cpp/BoostParts/boost/intrusive/slist_hook.hpp @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2012 +// (C) Copyright Ion Gaztanaga 2006-2013 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -40,7 +40,7 @@ struct get_slist_node_algo #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_slist_base_hook { @@ -54,11 +54,11 @@ struct make_slist_base_hook #endif >::type packed_options; - typedef detail::generic_hook + typedef generic_hook < get_slist_node_algo , typename packed_options::tag , packed_options::link_mode - , detail::SlistBaseHook + , SlistBaseHookId > implementation_defined; /// @endcond typedef implementation_defined type; @@ -168,7 +168,7 @@ class slist_base_hook #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template #else -template +template #endif struct make_slist_member_hook { @@ -182,11 +182,11 @@ struct make_slist_member_hook #endif >::type packed_options; - typedef detail::generic_hook + typedef generic_hook < get_slist_node_algo , member_tag , packed_options::link_mode - , detail::NoBaseHook + , NoBaseHookId > implementation_defined; /// @endcond typedef implementation_defined type; diff --git a/cpp/BoostParts/boost/lexical_cast.hpp b/cpp/BoostParts/boost/lexical_cast.hpp index 66e53700..ed2291d8 100644 --- a/cpp/BoostParts/boost/lexical_cast.hpp +++ b/cpp/BoostParts/boost/lexical_cast.hpp @@ -69,11 +69,6 @@ throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))) #endif -#if (defined(BOOST_LCAST_HAS_INT128) && !defined(__GNUC__)) || GCC_VERSION > 40700 -#define BOOST_LCAST_HAS_INT128 -#endif - - namespace boost { // exception used to indicate runtime lexical_cast failure @@ -316,7 +311,7 @@ namespace boost { > {}; #endif -#ifdef BOOST_LCAST_HAS_INT128 +#ifdef BOOST_HAS_INT128 template <> struct stream_char_common< boost::int128_type >: public boost::mpl::identity< char > {}; template <> struct stream_char_common< boost::uint128_type >: public boost::mpl::identity< char > {}; #endif @@ -613,7 +608,7 @@ namespace boost { BOOST_LCAST_DEF(unsigned __int64) BOOST_LCAST_DEF( __int64) #endif -#ifdef BOOST_LCAST_HAS_INT128 +#ifdef BOOST_HAS_INT128 BOOST_LCAST_DEF(boost::int128_type) BOOST_LCAST_DEF(boost::uint128_type) #endif @@ -879,6 +874,15 @@ namespace boost { { #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); + + // GCC when used with flag -std=c++0x may not have std::numeric_limits + // specializations for __int128 and unsigned __int128 types. + // Try compilation with -std=gnu++0x or -std=gnu++11. + // + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40856 + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::is_specialized, + "std::numeric_limits are not specialized for integral type passed to boost::lexical_cast" + ); #endif CharT const czero = lcast_char_constants::zero; --end; @@ -1612,6 +1616,11 @@ namespace boost { // does not support such conversions. Try updating it. BOOST_STATIC_ASSERT((boost::is_same::value)); #endif + +#ifndef BOOST_NO_EXCEPTIONS + out_stream.exceptions(std::ios::badbit); + try { +#endif bool const result = !(out_stream << input).fail(); const buffer_t* const p = static_cast( static_cast*>(out_stream.rdbuf()) @@ -1619,6 +1628,11 @@ namespace boost { start = p->pbase(); finish = p->pptr(); return result; +#ifndef BOOST_NO_EXCEPTIONS + } catch (const ::std::ios_base::failure& /*f*/) { + return false; + } +#endif } template @@ -1827,7 +1841,7 @@ namespace boost { bool operator<<( __int64 n) { return shl_signed(n); } #endif -#ifdef BOOST_LCAST_HAS_INT128 +#ifdef BOOST_HAS_INT128 bool operator<<(const boost::uint128_type& n) { start = lcast_put_unsigned(n, finish); return true; } bool operator<<(const boost::int128_type& n) { return shl_signed(n); } #endif @@ -1992,6 +2006,10 @@ namespace boost { #endif // BOOST_NO_STD_LOCALE #endif // BOOST_NO_STRINGSTREAM +#ifndef BOOST_NO_EXCEPTIONS + stream.exceptions(std::ios::badbit); + try { +#endif stream.unsetf(std::ios::skipws); lcast_set_precision(stream, static_cast(0)); @@ -2006,6 +2024,12 @@ namespace boost { #else Traits::eof(); #endif + +#ifndef BOOST_NO_EXCEPTIONS + } catch (const ::std::ios_base::failure& /*f*/) { + return false; + } +#endif } template @@ -2039,7 +2063,7 @@ namespace boost { bool operator>>(__int64& output) { return shr_signed(output); } #endif -#ifdef BOOST_LCAST_HAS_INT128 +#ifdef BOOST_HAS_INT128 bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); } bool operator>>(boost::int128_type& output) { return shr_signed(output); } #endif @@ -2553,7 +2577,7 @@ namespace boost { ); } #endif -#ifndef BOOST_NO_CHAR16_T +#ifndef BOOST_NO_CXX11_CHAR16_T template inline Target lexical_cast(const char16_t* chars, std::size_t count) { @@ -2562,7 +2586,7 @@ namespace boost { ); } #endif -#ifndef BOOST_NO_CHAR32_T +#ifndef BOOST_NO_CXX11_CHAR32_T template inline Target lexical_cast(const char32_t* chars, std::size_t count) { @@ -2719,7 +2743,6 @@ namespace boost { #undef BOOST_LCAST_THROW_BAD_CAST #undef BOOST_LCAST_NO_WCHAR_T -#undef BOOST_LCAST_HAS_INT128 #endif // BOOST_LEXICAL_CAST_INCLUDED diff --git a/cpp/BoostParts/boost/lockfree/detail/copy_payload.hpp b/cpp/BoostParts/boost/lockfree/detail/copy_payload.hpp index 1e83eb29..4836db4d 100644 --- a/cpp/BoostParts/boost/lockfree/detail/copy_payload.hpp +++ b/cpp/BoostParts/boost/lockfree/detail/copy_payload.hpp @@ -44,6 +44,23 @@ void copy_payload(T & t, U & u) copy_type::copy(t, u); } +template +struct consume_via_copy +{ + consume_via_copy(T & out): + out(out) + {} + + template + void operator()(U & element) + { + copy_payload(element, out); + } + + T & out; +}; + + }}} #endif /* BOOST_LOCKFREE_DETAIL_COPY_PAYLOAD_HPP_INCLUDED */ diff --git a/cpp/BoostParts/boost/lockfree/detail/freelist.hpp b/cpp/BoostParts/boost/lockfree/detail/freelist.hpp index 87a2bb14..739df08e 100644 --- a/cpp/BoostParts/boost/lockfree/detail/freelist.hpp +++ b/cpp/BoostParts/boost/lockfree/detail/freelist.hpp @@ -1,6 +1,6 @@ // lock-free freelist // -// Copyright (C) 2008, 2009, 2011 Tim Blechmann +// Copyright (C) 2008-2013 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -22,6 +22,12 @@ #include #include +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4100) // unreferenced formal parameter +#pragma warning(disable: 4127) // conditional expression is constant +#endif + namespace boost { namespace lockfree { namespace detail { @@ -110,7 +116,7 @@ public: ~freelist_stack(void) { - tagged_node_ptr current (pool_); + tagged_node_ptr current = pool_.load(); while (current) { freelist_node * current_ptr = current.get_ptr(); @@ -634,4 +640,9 @@ struct select_tagged_handle } /* namespace lockfree */ } /* namespace boost */ +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + + #endif /* BOOST_LOCKFREE_FREELIST_HPP_INCLUDED */ diff --git a/cpp/BoostParts/boost/lockfree/queue.hpp b/cpp/BoostParts/boost/lockfree/queue.hpp index 77526006..2b8fe2c6 100644 --- a/cpp/BoostParts/boost/lockfree/queue.hpp +++ b/cpp/BoostParts/boost/lockfree/queue.hpp @@ -25,6 +25,12 @@ #include #include +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4324) // structure was padded due to __declspec(align()) +#endif + + namespace boost { namespace lockfree { namespace detail { @@ -541,4 +547,8 @@ private: } /* namespace lockfree */ } /* namespace boost */ +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + #endif /* BOOST_LOCKFREE_FIFO_HPP_INCLUDED */ diff --git a/cpp/BoostParts/boost/lockfree/spsc_queue.hpp b/cpp/BoostParts/boost/lockfree/spsc_queue.hpp index 11031088..baae4bab 100644 --- a/cpp/BoostParts/boost/lockfree/spsc_queue.hpp +++ b/cpp/BoostParts/boost/lockfree/spsc_queue.hpp @@ -1,7 +1,7 @@ // lock-free single-producer/single-consumer ringbuffer // this algorithm is implemented in various projects (linux kernel) // -// Copyright (C) 2009, 2011 Tim Blechmann +// Copyright (C) 2009-2013 Tim Blechmann // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -11,13 +11,17 @@ #define BOOST_LOCKFREE_SPSC_QUEUE_HPP_INCLUDED #include +#include -#include +#include #include #ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS #include #endif #include +#include + +#include #include #include @@ -84,13 +88,13 @@ protected: bool push(T const & t, T * buffer, size_t max_size) { - size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread - size_t next = next_index(write_index, max_size); + const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread + const size_t next = next_index(write_index, max_size); if (next == read_index_.load(memory_order_acquire)) return false; /* ringbuffer is full */ - buffer[write_index] = t; + new (buffer + write_index) T(t); // copy-construct write_index_.store(next, memory_order_release); @@ -99,41 +103,15 @@ protected: size_t push(const T * input_buffer, size_t input_count, T * internal_buffer, size_t max_size) { - size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread - const size_t read_index = read_index_.load(memory_order_acquire); - const size_t avail = write_available(write_index, read_index, max_size); - - if (avail == 0) - return 0; - - input_count = (std::min)(input_count, avail); - - size_t new_write_index = write_index + input_count; - - if (write_index + input_count > max_size) { - /* copy data in two sections */ - size_t count0 = max_size - write_index; - - std::copy(input_buffer, input_buffer + count0, internal_buffer + write_index); - std::copy(input_buffer + count0, input_buffer + input_count, internal_buffer); - new_write_index -= max_size; - } else { - std::copy(input_buffer, input_buffer + input_count, internal_buffer + write_index); - - if (new_write_index == max_size) - new_write_index = 0; - } - - write_index_.store(new_write_index, memory_order_release); - return input_count; + return push(input_buffer, input_buffer + input_count, internal_buffer, max_size) - input_buffer; } template ConstIterator push(ConstIterator begin, ConstIterator end, T * internal_buffer, size_t max_size) { - // FIXME: avoid std::distance and std::advance + // FIXME: avoid std::distance - size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread + const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread const size_t read_index = read_index_.load(memory_order_acquire); const size_t avail = write_available(write_index, read_index, max_size); @@ -145,20 +123,18 @@ protected: size_t new_write_index = write_index + input_count; - ConstIterator last = begin; - std::advance(last, input_count); + const ConstIterator last = boost::next(begin, input_count); if (write_index + input_count > max_size) { /* copy data in two sections */ - size_t count0 = max_size - write_index; - ConstIterator midpoint = begin; - std::advance(midpoint, count0); + const size_t count0 = max_size - write_index; + const ConstIterator midpoint = boost::next(begin, count0); - std::copy(begin, midpoint, internal_buffer + write_index); - std::copy(midpoint, last, internal_buffer); + std::uninitialized_copy(begin, midpoint, internal_buffer + write_index); + std::uninitialized_copy(midpoint, last, internal_buffer); new_write_index -= max_size; } else { - std::copy(begin, last, internal_buffer + write_index); + std::uninitialized_copy(begin, last, internal_buffer + write_index); if (new_write_index == max_size) new_write_index = 0; @@ -170,21 +146,23 @@ protected: bool pop (T & ret, T * buffer, size_t max_size) { - size_t write_index = write_index_.load(memory_order_acquire); - size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread + const size_t write_index = write_index_.load(memory_order_acquire); + const size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread if (empty(write_index, read_index)) return false; ret = buffer[read_index]; + buffer[read_index].~T(); + size_t next = next_index(read_index, max_size); read_index_.store(next, memory_order_release); return true; } - size_t pop (T * output_buffer, size_t output_count, const T * internal_buffer, size_t max_size) + size_t pop (T * output_buffer, size_t output_count, T * internal_buffer, size_t max_size) { const size_t write_index = write_index_.load(memory_order_acquire); - size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread + const size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread const size_t avail = read_available(write_index, read_index, max_size); @@ -197,15 +175,15 @@ protected: if (read_index + output_count > max_size) { /* copy data in two sections */ - size_t count0 = max_size - read_index; - size_t count1 = output_count - count0; + const size_t count0 = max_size - read_index; + const size_t count1 = output_count - count0; - std::copy(internal_buffer + read_index, internal_buffer + max_size, output_buffer); - std::copy(internal_buffer, internal_buffer + count1, output_buffer + count0); + copy_and_delete(internal_buffer + read_index, internal_buffer + max_size, output_buffer); + copy_and_delete(internal_buffer, internal_buffer + count1, output_buffer + count0); new_read_index -= max_size; } else { - std::copy(internal_buffer + read_index, internal_buffer + read_index + output_count, output_buffer); + copy_and_delete(internal_buffer + read_index, internal_buffer + read_index + output_count, output_buffer); if (new_read_index == max_size) new_read_index = 0; } @@ -215,10 +193,10 @@ protected: } template - size_t pop (OutputIterator it, const T * internal_buffer, size_t max_size) + size_t pop (OutputIterator it, T * internal_buffer, size_t max_size) { const size_t write_index = write_index_.load(memory_order_acquire); - size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread + const size_t read_index = read_index_.load(memory_order_relaxed); // only written from pop thread const size_t avail = read_available(write_index, read_index, max_size); if (avail == 0) @@ -228,15 +206,15 @@ protected: if (read_index + avail > max_size) { /* copy data in two sections */ - size_t count0 = max_size - read_index; - size_t count1 = avail - count0; + const size_t count0 = max_size - read_index; + const size_t count1 = avail - count0; - it = std::copy(internal_buffer + read_index, internal_buffer + max_size, it); - std::copy(internal_buffer, internal_buffer + count1, it); + it = copy_and_delete(internal_buffer + read_index, internal_buffer + max_size, it); + copy_and_delete(internal_buffer, internal_buffer + count1, it); new_read_index -= max_size; } else { - std::copy(internal_buffer + read_index, internal_buffer + read_index + avail, it); + copy_and_delete(internal_buffer + read_index, internal_buffer + read_index + avail, it); if (new_read_index == max_size) new_read_index = 0; } @@ -282,34 +260,58 @@ private: { return write_index == read_index; } + + template< class OutputIterator > + OutputIterator copy_and_delete( T * first, T * last, OutputIterator out ) + { + if (boost::has_trivial_destructor::value) { + return std::copy(first, last, out); // will use memcpy if possible + } else { + for (; first != last; ++first, ++out) { + *out = *first; + first->~T(); + } + return out; + } + } }; template class compile_time_sized_ringbuffer: public ringbuffer_base { - typedef std::size_t size_t; + typedef std::size_t size_type; static const std::size_t max_size = MaxSize + 1; - boost::array array_; + + typedef typename boost::aligned_storage::value + >::type storage_type; + + storage_type storage_; + + T * data() + { + return static_cast(storage_.address()); + } public: bool push(T const & t) { - return ringbuffer_base::push(t, array_.c_array(), max_size); + return ringbuffer_base::push(t, data(), max_size); } bool pop(T & ret) { - return ringbuffer_base::pop(ret, array_.c_array(), max_size); + return ringbuffer_base::pop(ret, data(), max_size); } - size_t push(T const * t, size_t size) + size_type push(T const * t, size_type size) { - return ringbuffer_base::push(t, size, array_.c_array(), max_size); + return ringbuffer_base::push(t, size, data(), max_size); } - template - size_t push(T const (&t)[size]) + template + size_type push(T const (&t)[size]) { return push(t, size); } @@ -317,24 +319,24 @@ public: template ConstIterator push(ConstIterator begin, ConstIterator end) { - return ringbuffer_base::push(begin, end, array_.c_array(), max_size); + return ringbuffer_base::push(begin, end, data(), max_size); } - size_t pop(T * ret, size_t size) + size_type pop(T * ret, size_type size) { - return ringbuffer_base::pop(ret, size, array_.c_array(), max_size); + return ringbuffer_base::pop(ret, size, data(), max_size); } - template - size_t pop(T (&ret)[size]) + template + size_type pop(T (&ret)[size]) { return pop(ret, size); } template - size_t pop(OutputIterator it) + size_type pop(OutputIterator it) { - return ringbuffer_base::pop(it, array_.c_array(), max_size); + return ringbuffer_base::pop(it, data(), max_size); } }; @@ -343,44 +345,37 @@ class runtime_sized_ringbuffer: public ringbuffer_base, private Alloc { - typedef std::size_t size_t; - size_t max_elements_; + typedef std::size_t size_type; + size_type max_elements_; typedef typename Alloc::pointer pointer; pointer array_; public: - explicit runtime_sized_ringbuffer(size_t max_elements): + explicit runtime_sized_ringbuffer(size_type max_elements): max_elements_(max_elements + 1) { - // TODO: we don't necessarily need to construct all elements array_ = Alloc::allocate(max_elements_); - for (size_t i = 0; i != max_elements_; ++i) - Alloc::construct(array_ + i, T()); } template - runtime_sized_ringbuffer(typename Alloc::template rebind::other const & alloc, size_t max_elements): + runtime_sized_ringbuffer(typename Alloc::template rebind::other const & alloc, size_type max_elements): Alloc(alloc), max_elements_(max_elements + 1) { - // TODO: we don't necessarily need to construct all elements array_ = Alloc::allocate(max_elements_); - for (size_t i = 0; i != max_elements_; ++i) - Alloc::construct(array_ + i, T()); } - runtime_sized_ringbuffer(Alloc const & alloc, size_t max_elements): + runtime_sized_ringbuffer(Alloc const & alloc, size_type max_elements): Alloc(alloc), max_elements_(max_elements + 1) { - // TODO: we don't necessarily need to construct all elements array_ = Alloc::allocate(max_elements_); - for (size_t i = 0; i != max_elements_; ++i) - Alloc::construct(array_ + i, T()); } ~runtime_sized_ringbuffer(void) { - for (size_t i = 0; i != max_elements_; ++i) - Alloc::destroy(array_ + i); + // destroy all remaining items + T out; + while (pop(out)) {}; + Alloc::deallocate(array_, max_elements_); } @@ -394,13 +389,13 @@ public: return ringbuffer_base::pop(ret, &*array_, max_elements_); } - size_t push(T const * t, size_t size) + size_type push(T const * t, size_type size) { return ringbuffer_base::push(t, size, &*array_, max_elements_); } - template - size_t push(T const (&t)[size]) + template + size_type push(T const (&t)[size]) { return push(t, size); } @@ -411,19 +406,19 @@ public: return ringbuffer_base::push(begin, end, array_, max_elements_); } - size_t pop(T * ret, size_t size) + size_type pop(T * ret, size_type size) { return ringbuffer_base::pop(ret, size, array_, max_elements_); } - template - size_t pop(T (&ret)[size]) + template + size_type pop(T (&ret)[size]) { return pop(ret, size); } template - size_t pop(OutputIterator it) + size_type pop(OutputIterator it) { return ringbuffer_base::pop(it, array_, max_elements_); } diff --git a/cpp/BoostParts/boost/lockfree/stack.hpp b/cpp/BoostParts/boost/lockfree/stack.hpp index efa95247..c15296a8 100644 --- a/cpp/BoostParts/boost/lockfree/stack.hpp +++ b/cpp/BoostParts/boost/lockfree/stack.hpp @@ -435,21 +435,9 @@ public: bool pop(U & ret) { BOOST_STATIC_ASSERT((boost::is_convertible::value)); - tagged_node_handle old_tos = tos.load(detail::memory_order_consume); + detail::consume_via_copy consumer(ret); - for (;;) { - node * old_tos_pointer = pool.get_pointer(old_tos); - if (!old_tos_pointer) - return false; - - tagged_node_handle new_tos(old_tos_pointer->next, old_tos.get_next_tag()); - - if (tos.compare_exchange_weak(old_tos, new_tos)) { - detail::copy_payload(old_tos_pointer->v, ret); - pool.template destruct(old_tos); - return true; - } - } + return consume_one(consumer); } @@ -505,24 +493,42 @@ public: template bool consume_one(Functor & f) { - T element; - bool success = pop(element); - if (success) - f(element); + tagged_node_handle old_tos = tos.load(detail::memory_order_consume); - return success; + for (;;) { + node * old_tos_pointer = pool.get_pointer(old_tos); + if (!old_tos_pointer) + return false; + + tagged_node_handle new_tos(old_tos_pointer->next, old_tos.get_next_tag()); + + if (tos.compare_exchange_weak(old_tos, new_tos)) { + f(old_tos_pointer->v); + pool.template destruct(old_tos); + return true; + } + } } /// \copydoc boost::lockfree::stack::consume_one(Functor & rhs) template bool consume_one(Functor const & f) { - T element; - bool success = pop(element); - if (success) - f(element); + tagged_node_handle old_tos = tos.load(detail::memory_order_consume); - return success; + for (;;) { + node * old_tos_pointer = pool.get_pointer(old_tos); + if (!old_tos_pointer) + return false; + + tagged_node_handle new_tos(old_tos_pointer->next, old_tos.get_next_tag()); + + if (tos.compare_exchange_weak(old_tos, new_tos)) { + f(old_tos_pointer->v); + pool.template destruct(old_tos); + return true; + } + } } /** consumes all elements via a functor diff --git a/cpp/BoostParts/boost/math/special_functions/fpclassify.hpp b/cpp/BoostParts/boost/math/special_functions/fpclassify.hpp index 02a98fb6..75f57b03 100644 --- a/cpp/BoostParts/boost/math/special_functions/fpclassify.hpp +++ b/cpp/BoostParts/boost/math/special_functions/fpclassify.hpp @@ -258,7 +258,7 @@ inline int fpclassify BOOST_NO_MACRO_EXPAND(T t) { typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename tools::promote_args::type value_type; + typedef typename tools::promote_args_permissive::type value_type; #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(0))) return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); @@ -338,7 +338,7 @@ inline bool (isfinite)(T x) typedef typename detail::fp_traits::type traits; typedef typename traits::method method; // typedef typename boost::is_floating_point::type fp_tag; - typedef typename tools::promote_args::type value_type; + typedef typename tools::promote_args_permissive::type value_type; return detail::isfinite_impl(static_cast(x), method()); } @@ -409,7 +409,7 @@ inline bool (isnormal)(T x) typedef typename detail::fp_traits::type traits; typedef typename traits::method method; //typedef typename boost::is_floating_point::type fp_tag; - typedef typename tools::promote_args::type value_type; + typedef typename tools::promote_args_permissive::type value_type; return detail::isnormal_impl(static_cast(x), method()); } @@ -498,7 +498,7 @@ inline bool (isinf)(T x) typedef typename detail::fp_traits::type traits; typedef typename traits::method method; // typedef typename boost::is_floating_point::type fp_tag; - typedef typename tools::promote_args::type value_type; + typedef typename tools::promote_args_permissive::type value_type; return detail::isinf_impl(static_cast(x), method()); } diff --git a/cpp/BoostParts/boost/math/special_functions/math_fwd.hpp b/cpp/BoostParts/boost/math/special_functions/math_fwd.hpp index 337b3bb4..9de38ec0 100644 --- a/cpp/BoostParts/boost/math/special_functions/math_fwd.hpp +++ b/cpp/BoostParts/boost/math/special_functions/math_fwd.hpp @@ -768,10 +768,10 @@ namespace boost int sign BOOST_NO_MACRO_EXPAND(const T& z); template - typename tools::promote_args::type copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y); + typename tools::promote_args_permissive::type copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y); template - typename tools::promote_args::type changesign BOOST_NO_MACRO_EXPAND(const T& z); + typename tools::promote_args_permissive::type changesign BOOST_NO_MACRO_EXPAND(const T& z); // Exponential integrals: namespace detail{ diff --git a/cpp/BoostParts/boost/math/special_functions/sign.hpp b/cpp/BoostParts/boost/math/special_functions/sign.hpp index 51b5bbc3..75fb0129 100644 --- a/cpp/BoostParts/boost/math/special_functions/sign.hpp +++ b/cpp/BoostParts/boost/math/special_functions/sign.hpp @@ -111,7 +111,7 @@ template int (signbit)(T x) typedef typename detail::fp_traits::type traits; typedef typename traits::method method; // typedef typename boost::is_floating_point::type fp_tag; - typedef typename tools::promote_args::type result_type; + typedef typename tools::promote_args_permissive::type result_type; return detail::signbit_impl(static_cast(x), method()); } @@ -121,22 +121,22 @@ inline int sign BOOST_NO_MACRO_EXPAND(const T& z) return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1; } -template typename tools::promote_args::type (changesign)(const T& x) +template typename tools::promote_args_permissive::type (changesign)(const T& x) { //!< \brief return unchanged binary pattern of x, except for change of sign bit. typedef typename detail::fp_traits::sign_change_type traits; typedef typename traits::method method; // typedef typename boost::is_floating_point::type fp_tag; - typedef typename tools::promote_args::type result_type; + typedef typename tools::promote_args_permissive::type result_type; return detail::changesign_impl(static_cast(x), method()); } template -inline typename tools::promote_args::type +inline typename tools::promote_args_permissive::type copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y) { BOOST_MATH_STD_USING - typedef typename tools::promote_args::type result_type; + typedef typename tools::promote_args_permissive::type result_type; return (boost::math::signbit)(static_cast(x)) != (boost::math::signbit)(static_cast(y)) ? (boost::math::changesign)(static_cast(x)) : static_cast(x); } diff --git a/cpp/BoostParts/boost/math/tools/promotion.hpp b/cpp/BoostParts/boost/math/tools/promotion.hpp index 728aaf12..b3ad2040 100644 --- a/cpp/BoostParts/boost/math/tools/promotion.hpp +++ b/cpp/BoostParts/boost/math/tools/promotion.hpp @@ -138,10 +138,35 @@ namespace boost // // Guard against use of long double if it's not supported: // - BOOST_STATIC_ASSERT((0 == ::boost::is_same::value)); + BOOST_STATIC_ASSERT_MSG((0 == ::boost::is_same::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented."); #endif }; + // + // This struct is the same as above, but has no static assert on long double usage, + // it should be used only on functions that can be implemented for long double + // even when std lib support is missing or broken for that type. + // + template + struct promote_args_permissive + { + typedef typename promote_args_2< + typename remove_cv::type, + typename promote_args_2< + typename remove_cv::type, + typename promote_args_2< + typename remove_cv::type, + typename promote_args_2< + typename remove_cv::type, + typename promote_args_2< + typename remove_cv::type, typename remove_cv::type + >::type + >::type + >::type + >::type + >::type type; + }; + } // namespace tools } // namespace math } // namespace boost diff --git a/cpp/BoostParts/boost/move/algorithm.hpp b/cpp/BoostParts/boost/move/algorithm.hpp index 36a46bec..43a81c37 100644 --- a/cpp/BoostParts/boost/move/algorithm.hpp +++ b/cpp/BoostParts/boost/move/algorithm.hpp @@ -18,7 +18,6 @@ #include #include -#include #include #include //copy, copy_backward diff --git a/cpp/BoostParts/boost/move/core.hpp b/cpp/BoostParts/boost/move/core.hpp index d939f036..9586ecad 100644 --- a/cpp/BoostParts/boost/move/core.hpp +++ b/cpp/BoostParts/boost/move/core.hpp @@ -18,17 +18,24 @@ #include +//boost_move_no_copy_constructor_or_assign typedef +//used to detect noncopyable types for other Boost libraries. #ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ private:\ TYPE(TYPE &);\ TYPE& operator=(TYPE &);\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ + private:\ // #else #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ public:\ TYPE(TYPE const &) = delete;\ TYPE& operator=(TYPE const &) = delete;\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ private:\ // #endif //BOOST_NO_CXX11_DELETED_FUNCTIONS diff --git a/cpp/BoostParts/boost/move/detail/move_helpers.hpp b/cpp/BoostParts/boost/move/detail/move_helpers.hpp index ddfea9bc..ed6f3d53 100644 --- a/cpp/BoostParts/boost/move/detail/move_helpers.hpp +++ b/cpp/BoostParts/boost/move/detail/move_helpers.hpp @@ -19,6 +19,8 @@ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined(_MSC_VER) && (_MSC_VER == 1600)) #include +#include +#include #include #endif #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) @@ -28,6 +30,7 @@ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) struct not_a_type; +struct not_a_type2; #define BOOST_MOVE_CATCH_CONST(U) \ typename ::boost::mpl::if_< ::boost::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type #define BOOST_MOVE_CATCH_RVALUE(U)\ @@ -40,7 +43,6 @@ struct not_a_type; #endif #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES - #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(static_cast(x)); }\ @@ -72,7 +74,7 @@ struct not_a_type; return FWD_FUNCTION(::boost::move(t));\ }\ // - +// ::boost::is_convertible::value && #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ @@ -108,7 +110,7 @@ struct not_a_type; #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ @@ -119,8 +121,7 @@ struct not_a_type; { return FWD_FUNCTION(arg1, const_cast(x)); }\ \ template\ - typename ::boost::enable_if_c\ - < ::boost::is_class::value &&\ + typename ::boost::enable_if_c<\ ::boost::is_same::value &&\ !::boost::has_move_emulation_enabled::value\ , RETURN_VALUE >::type\ @@ -128,10 +129,10 @@ struct not_a_type; { return FWD_FUNCTION(arg1, u); }\ \ template\ - typename ::boost::enable_if_c\ - < (!::boost::is_class::value || \ - !::boost::move_detail::is_rv::value) && \ - !::boost::is_same::value \ + typename ::boost::enable_if_c<\ + !::boost::move_detail::is_rv::value && \ + !::boost::is_same::value && \ + !::boost::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -142,7 +143,7 @@ struct not_a_type; #elif (defined(_MSC_VER) && (_MSC_VER == 1600)) -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ @@ -151,7 +152,8 @@ struct not_a_type; \ template\ typename ::boost::enable_if_c\ - < !::boost::is_same::value\ + < !::boost::is_same::value && \ + !::boost::is_convertible::value \ , RETURN_VALUE >::type\ PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ {\ @@ -162,7 +164,7 @@ struct not_a_type; #else -#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1)\ +#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ { return FWD_FUNCTION(arg1, static_cast(x)); }\ \ diff --git a/cpp/BoostParts/boost/move/traits.hpp b/cpp/BoostParts/boost/move/traits.hpp index e5c84447..ced1cdd9 100644 --- a/cpp/BoostParts/boost/move/traits.hpp +++ b/cpp/BoostParts/boost/move/traits.hpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES @@ -38,11 +40,17 @@ struct has_trivial_destructor_after_move : ::boost::has_trivial_destructor {}; -//! By default this traits returns false. Classes with non-throwing move constructor +//! By default this traits returns +//!
boost::is_nothrow_move_constructible::value && boost::is_nothrow_move_assignable::value 
. +//! Classes with non-throwing move constructor //! and assignment can specialize this trait to obtain some performance improvements. template struct has_nothrow_move - : public ::boost::move_detail::integral_constant + : public ::boost::move_detail::integral_constant + < bool + , boost::is_nothrow_move_constructible::value && + boost::is_nothrow_move_assignable::value + > {}; namespace move_detail { diff --git a/cpp/BoostParts/boost/move/utility.hpp b/cpp/BoostParts/boost/move/utility.hpp index fb2ec69c..964500eb 100644 --- a/cpp/BoostParts/boost/move/utility.hpp +++ b/cpp/BoostParts/boost/move/utility.hpp @@ -37,7 +37,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && !has_move_emulation_enabled::value, T&>::type - move(T& x) + move(T& x) BOOST_NOEXCEPT { return x; } @@ -45,7 +45,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type - move(T& x) + move(T& x) BOOST_NOEXCEPT { return *static_cast* >(::boost::move_detail::addressof(x)); } @@ -53,7 +53,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && has_move_emulation_enabled::value, rv&>::type - move(rv& x) + move(rv& x) BOOST_NOEXCEPT { return x; } @@ -67,7 +67,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && ::boost::move_detail::is_rv::value, T &>::type - forward(const typename ::boost::move_detail::identity::type &x) + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return const_cast(x); } @@ -75,7 +75,7 @@ template inline typename ::boost::move_detail::enable_if_c < enable_move_utility_emulation::value && !::boost::move_detail::is_rv::value, const T &>::type - forward(const typename ::boost::move_detail::identity::type &x) + forward(const typename ::boost::move_detail::identity::type &x) BOOST_NOEXCEPT { return x; } @@ -123,19 +123,19 @@ //! in compilers with rvalue references. For other compilers converts T & into //! ::boost::rv & so that move emulation is activated. template - rvalue_reference move (input_reference); + rvalue_reference move(input_reference) noexcept; #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references template - inline typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return t; } #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES template - inline typename remove_reference::type && move(T&& t) + inline typename remove_reference::type && move(T&& t) BOOST_NOEXCEPT { return static_cast::type &&>(t); } #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES @@ -159,13 +159,13 @@ //! ::boost::rv & //! //! * Else, output_reference is equal to input_reference. - template output_reference forward(input_reference); + template output_reference forward(input_reference) noexcept; #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES) //Old move approach, lvalues could bind to rvalue references template - inline T&& forward (typename ::boost::move_detail::identity::type&& t) + inline T&& forward(typename ::boost::move_detail::identity::type&& t) BOOST_NOEXCEPT { return t; } #else //Old move @@ -178,7 +178,7 @@ move_detail::is_lvalue_reference::value ? move_detail::is_lvalue_reference::value : true>::type * = 0/* , typename ::boost::move_detail::enable_if_c< move_detail::is_convertible - ::type*, typename remove_reference::type*>::value>::type * = 0*/) + ::type*, typename remove_reference::type*>::value>::type * = 0*/) BOOST_NOEXCEPT { return static_cast(t); } #endif //BOOST_MOVE_DOXYGEN_INVOKED diff --git a/cpp/BoostParts/boost/mpi/collectives.hpp b/cpp/BoostParts/boost/mpi/collectives.hpp index 76d6bda3..e74fd72b 100644 --- a/cpp/BoostParts/boost/mpi/collectives.hpp +++ b/cpp/BoostParts/boost/mpi/collectives.hpp @@ -19,10 +19,10 @@ #define BOOST_MPI_COLLECTIVES_HPP #include +#include #include namespace boost { namespace mpi { - /** * @brief Gather the values stored at every process into vectors of * values from each process. @@ -94,12 +94,15 @@ all_gather(const communicator& comm, const T* in_values, int n, T* out_values); * * @param comm The communicator over which the reduction will * occur. - * - * @param in_value The local value to be combined with the local + * @param value The local value to be combined with the local * values of every other process. For reducing arrays, @c in_values * is a pointer to the local values to be reduced and @c n is the * number of values to reduce. See @c reduce for more information. * + * If wrapped in a @c inplace_t object, combine the usage of both + * input and $c out_value and the local value will be overwritten + * (a convenience function @c inplace is provided for the wrapping). + * * @param out_value Will receive the result of the reduction * operation. If this parameter is omitted, the outgoing value will * instead be returned. @@ -116,26 +119,39 @@ all_gather(const communicator& comm, const T* in_values, int n, T* out_values); * gives the implementation additional lattitude to optimize the * reduction operation. * + * @param n Indicated the size of the buffers of array type. * @returns If no @p out_value parameter is supplied, returns the * result of the reduction operation. */ template void -all_reduce(const communicator& comm, const T& in_value, T& out_value, Op op); - +all_reduce(const communicator& comm, const T* value, int n, T* out_value, + Op op); /** * \overload */ template -T all_reduce(const communicator& comm, const T& in_value, Op op); +void +all_reduce(const communicator& comm, const T& value, T& out_value, Op op); +/** + * \overload + */ +template +T all_reduce(const communicator& comm, const T& value, Op op); /** * \overload */ template void -all_reduce(const communicator& comm, const T* in_values, int n, T* out_values, +all_reduce(const communicator& comm, inplace_t value, int n, Op op); +/** + * \overload + */ +template +void +all_reduce(const communicator& comm, inplace_t value, Op op); /** * @brief Send data from every process to every other process. diff --git a/cpp/BoostParts/boost/mpi/collectives/all_reduce.hpp b/cpp/BoostParts/boost/mpi/collectives/all_reduce.hpp index 26b8fc9c..06e116a6 100644 --- a/cpp/BoostParts/boost/mpi/collectives/all_reduce.hpp +++ b/cpp/BoostParts/boost/mpi/collectives/all_reduce.hpp @@ -12,12 +12,15 @@ #ifndef BOOST_MPI_ALL_REDUCE_HPP #define BOOST_MPI_ALL_REDUCE_HPP +#include + +#include + // All-reduce falls back to reduce() + broadcast() in some cases. #include #include namespace boost { namespace mpi { - namespace detail { /********************************************************************** * Simple reduction with MPI_Allreduce * @@ -67,7 +70,17 @@ namespace detail { T* out_values, Op op, mpl::false_ /*is_mpi_op*/, mpl::false_ /*is_mpi_datatype*/) { - reduce(comm, in_values, n, out_values, op, 0); + if (in_values == MPI_IN_PLACE) { + // if in_values matches the in place tag, then the output + // buffer actually contains the input data. + // But we can just go back to the out of place + // implementation in this case. + // it's not clear how/if we can avoid the copy. + std::vector tmp_in( out_values, out_values + n); + reduce(comm, &(tmp_in[0]), n, out_values, op, 0); + } else { + reduce(comm, in_values, n, out_values, op, 0); + } broadcast(comm, out_values, n, 0); } } // end namespace detail @@ -81,6 +94,20 @@ all_reduce(const communicator& comm, const T* in_values, int n, T* out_values, is_mpi_op(), is_mpi_datatype()); } +template +inline void +all_reduce(const communicator& comm, inplace_t inout_values, int n, Op op) +{ + all_reduce(comm, static_cast(MPI_IN_PLACE), n, inout_values.buffer, op); +} + +template +inline void +all_reduce(const communicator& comm, inplace_t inout_values, Op op) +{ + all_reduce(comm, static_cast(MPI_IN_PLACE), 1, &(inout_values.buffer), op); +} + template inline void all_reduce(const communicator& comm, const T& in_value, T& out_value, Op op) diff --git a/cpp/BoostParts/boost/mpi/collectives/gather.hpp b/cpp/BoostParts/boost/mpi/collectives/gather.hpp index 4f39392a..70dfd653 100644 --- a/cpp/BoostParts/boost/mpi/collectives/gather.hpp +++ b/cpp/BoostParts/boost/mpi/collectives/gather.hpp @@ -131,7 +131,12 @@ void gather(const communicator& comm, const T* in_values, int n, std::vector& out_values, int root) { - ::boost::mpi::gather(comm, in_values, n, &out_values[0], root); + if (comm.rank() == root) { + out_values.resize(comm.size() * n); + ::boost::mpi::gather(comm, in_values, n, &out_values[0], root); + } + else + ::boost::mpi::gather(comm, in_values, n, root); } template diff --git a/cpp/BoostParts/boost/mpi/collectives/reduce.hpp b/cpp/BoostParts/boost/mpi/collectives/reduce.hpp index f1dee823..8fc2fe6e 100644 --- a/cpp/BoostParts/boost/mpi/collectives/reduce.hpp +++ b/cpp/BoostParts/boost/mpi/collectives/reduce.hpp @@ -330,6 +330,25 @@ reduce(const communicator& comm, const T* in_values, int n, Op op, int root) is_mpi_op(), is_mpi_datatype()); } +template +void +reduce(const communicator & comm, std::vector const & in_values, Op op, + int root) +{ + reduce(comm, &in_values.front(), in_values.size(), op, root); +} + +template +void +reduce(const communicator & comm, std::vector const & in_values, + std::vector & out_values, Op op, int root) +{ + out_values.resize(in_values.size()); + reduce(comm, &in_values.front(), in_values.size(), &out_values.front(), op, + root); +} + + template void reduce(const communicator& comm, const T& in_value, T& out_value, Op op, diff --git a/cpp/BoostParts/boost/mpi/communicator.hpp b/cpp/BoostParts/boost/mpi/communicator.hpp index e450e2a5..65de3a47 100644 --- a/cpp/BoostParts/boost/mpi/communicator.hpp +++ b/cpp/BoostParts/boost/mpi/communicator.hpp @@ -13,6 +13,7 @@ #ifndef BOOST_MPI_COMMUNICATOR_HPP #define BOOST_MPI_COMMUNICATOR_HPP +#include #include #include #include @@ -869,6 +870,8 @@ class BOOST_MPI_DECL communicator { void operator()(MPI_Comm* comm) const { + BOOST_ASSERT( comm != 0 ); + BOOST_ASSERT(*comm != MPI_COMM_NULL); int finalized; BOOST_MPI_CHECK_RESULT(MPI_Finalized, (&finalized)); if (!finalized) diff --git a/cpp/BoostParts/boost/mpi/config.hpp b/cpp/BoostParts/boost/mpi/config.hpp index cf08e2cd..bee4cc17 100644 --- a/cpp/BoostParts/boost/mpi/config.hpp +++ b/cpp/BoostParts/boost/mpi/config.hpp @@ -27,7 +27,7 @@ // If this is an MPI-2 implementation, define configuration macros for // the features we are interested in. -#if defined(MPI_VERSION) && MPI_VERSION == 2 +#if defined(MPI_VERSION) && MPI_VERSION >= 2 /** @brief Determine if the MPI implementation has support for memory * allocation. * @@ -48,6 +48,11 @@ * environment class will provide a default constructor. This macro is * always defined for MPI-2 implementations. */ # define BOOST_MPI_HAS_NOARG_INITIALIZATION +#else +// If this is an MPI-1.x implementation, no arg initialization for +// mpi environement could still be available, but not mandatory. +// Undef this if no arg init is available: +//# define BOOST_MPI_HAS_NOARG_INITIALIZATION #endif #if defined(MPIAPI) diff --git a/cpp/BoostParts/boost/mpi/detail/binary_buffer_iprimitive.hpp b/cpp/BoostParts/boost/mpi/detail/binary_buffer_iprimitive.hpp index 2bc028fc..f499d0d5 100644 --- a/cpp/BoostParts/boost/mpi/detail/binary_buffer_iprimitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/binary_buffer_iprimitive.hpp @@ -21,6 +21,7 @@ #include #include #include // for memcpy +#include namespace boost { namespace mpi { @@ -107,7 +108,8 @@ private: void load_impl(void * p, int l) { assert(position+l<=static_cast(buffer_.size())); - std::memcpy(p,&buffer_[position],l); + if (l) + std::memcpy(p,&buffer_[position],l); position += l; } diff --git a/cpp/BoostParts/boost/mpi/detail/forward_skeleton_iarchive.hpp b/cpp/BoostParts/boost/mpi/detail/forward_skeleton_iarchive.hpp index 4d0ef7e9..6e118198 100644 --- a/cpp/BoostParts/boost/mpi/detail/forward_skeleton_iarchive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/forward_skeleton_iarchive.hpp @@ -61,6 +61,7 @@ BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::version_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_id_reference_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_id_type) +BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::object_reference_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::tracking_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(archive::class_name_type) BOOST_ARCHIVE_FORWARD_IMPLEMENTATION(serialization::collection_size_type) diff --git a/cpp/BoostParts/boost/mpi/detail/ignore_iprimitive.hpp b/cpp/BoostParts/boost/mpi/detail/ignore_iprimitive.hpp index 724d7115..eb3d2b78 100644 --- a/cpp/BoostParts/boost/mpi/detail/ignore_iprimitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/ignore_iprimitive.hpp @@ -44,7 +44,7 @@ public: /// don't do anything when loading primitive types template - void load(T & t) + void load(T &) { } }; diff --git a/cpp/BoostParts/boost/mpi/detail/ignore_oprimitive.hpp b/cpp/BoostParts/boost/mpi/detail/ignore_oprimitive.hpp index 9070ea7f..23375cad 100644 --- a/cpp/BoostParts/boost/mpi/detail/ignore_oprimitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/ignore_oprimitive.hpp @@ -52,7 +52,7 @@ public: /// don't do anything when saving primitive types template - void save(const T & t) + void save(const T &) { } }; diff --git a/cpp/BoostParts/boost/mpi/detail/mpi_datatype_primitive.hpp b/cpp/BoostParts/boost/mpi/detail/mpi_datatype_primitive.hpp index 3c22245d..0a607854 100644 --- a/cpp/BoostParts/boost/mpi/detail/mpi_datatype_primitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/mpi_datatype_primitive.hpp @@ -49,7 +49,11 @@ public: : is_committed(false), origin() { +#if defined(MPI_VERSION) && MPI_VERSION >= 2 + BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast(orig), &origin)); +#else BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast(orig), &origin)); +#endif } void save_binary(void const *address, std::size_t count) @@ -72,7 +76,8 @@ public: { if (!is_committed) { - BOOST_MPI_CHECK_RESULT(MPI_Type_struct, +#if defined(MPI_VERSION) && MPI_VERSION >= 2 + BOOST_MPI_CHECK_RESULT(MPI_Type_create_struct, ( addresses.size(), boost::serialization::detail::get_data(lengths), @@ -80,9 +85,18 @@ public: boost::serialization::detail::get_data(types), &datatype_ )); - +#else + BOOST_MPI_CHECK_RESULT(MPI_Type_struct, + ( + addresses.size(), + boost::serialization::detail::get_data(lengths), + boost::serialization::detail::get_data(addresses), + boost::serialization::detail::get_data(types), + &datatype_ + )); +#endif BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_)); - + is_committed = true; } @@ -105,8 +119,11 @@ private: // store address, type and length MPI_Aint a; - BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast(p), &a)); - +#if defined(MPI_VERSION) && MPI_VERSION >= 2 + BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast(p), &a)); +#else + BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast(p), &a)); +#endif addresses.push_back(a-origin); types.push_back(t); lengths.push_back(l); diff --git a/cpp/BoostParts/boost/mpi/detail/packed_iprimitive.hpp b/cpp/BoostParts/boost/mpi/detail/packed_iprimitive.hpp index 6e981c7f..bb471a7c 100644 --- a/cpp/BoostParts/boost/mpi/detail/packed_iprimitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/packed_iprimitive.hpp @@ -94,7 +94,9 @@ public: load(l); s.resize(l); // note breaking a rule here - could be a problem on some platform - load_impl(const_cast(s.data()),get_mpi_datatype(CharType()),l); + if (l) + load_impl(const_cast(s.data()), + get_mpi_datatype(CharType()),l); } private: diff --git a/cpp/BoostParts/boost/mpi/detail/packed_oprimitive.hpp b/cpp/BoostParts/boost/mpi/detail/packed_oprimitive.hpp index 1f59df89..5ac6835e 100644 --- a/cpp/BoostParts/boost/mpi/detail/packed_oprimitive.hpp +++ b/cpp/BoostParts/boost/mpi/detail/packed_oprimitive.hpp @@ -81,7 +81,8 @@ public: { unsigned int l = static_cast(s.size()); save(l); - save_impl(s.data(),get_mpi_datatype(CharType()),s.size()); + if (l) + save_impl(s.data(),get_mpi_datatype(CharType()),s.size()); } private: diff --git a/cpp/BoostParts/boost/mpi/environment.hpp b/cpp/BoostParts/boost/mpi/environment.hpp index 378a3b60..92af129f 100644 --- a/cpp/BoostParts/boost/mpi/environment.hpp +++ b/cpp/BoostParts/boost/mpi/environment.hpp @@ -17,9 +17,46 @@ #include #include #include +#include namespace boost { namespace mpi { +namespace threading { +/** @brief specify the supported threading level. + * + * Based on MPI 2 standard/8.7.3 + */ +enum level { + /** Only one thread will execute. + */ + single = MPI_THREAD_SINGLE, + /** Only main thread will do MPI calls. + * + * The process may be multi-threaded, but only the main + * thread will make MPI calls (all MPI calls are ``funneled'' + * to the main thread). + */ + funneled = MPI_THREAD_FUNNELED, + /** Only one thread at the time do MPI calls. + * + * The process may be multi-threaded, and multiple + * threads may make MPI calls, but only one at a time: + * MPI calls are not made concurrently from two distinct + * threads (all MPI calls are ``serialized''). + */ + serialized = MPI_THREAD_SERIALIZED, + /** Multiple thread may do MPI calls. + * + * Multiple threads may call MPI, with no restrictions. + */ + multiple = MPI_THREAD_MULTIPLE +}; +/** Formated output for threading level. */ +std::ostream& operator<<(std::ostream& out, level l); + +/** Formated input for threading level. */ +std::istream& operator>>(std::istream& in, level& l); +} // namespace threading /** @brief Initialize, finalize, and query the MPI environment. * * The @c environment class is used to initialize, finalize, and @@ -62,6 +99,22 @@ public: * program if it is destructed due to an uncaught exception. */ explicit environment(bool abort_on_exception = true); + /** Initialize the MPI environment. + * + * If the MPI environment has not already been initialized, + * initializes MPI with a call to @c MPI_Init_thread. Since this + * constructor does not take command-line arguments (@c argc and @c + * argv), it is only available when the underlying MPI + * implementation supports calling @c MPI_Init with @c NULL + * arguments, indicated by the macro @c + * BOOST_MPI_HAS_NOARG_INITIALIZATION. + * + * @param mt_level the required level of threading support. + * + * @param abort_on_exception When true, this object will abort the + * program if it is destructed due to an uncaught exception. + */ + explicit environment(threading::level mt_level, bool abort_on_exception = true); #endif /** Initialize the MPI environment. @@ -80,6 +133,25 @@ public: */ environment(int& argc, char** &argv, bool abort_on_exception = true); + /** Initialize the MPI environment. + * + * If the MPI environment has not already been initialized, + * initializes MPI with a call to @c MPI_Init_thread. + * + * @param argc The number of arguments provided in @p argv, as + * passed into the program's @c main function. + * + * @param argv The array of argument strings passed to the program + * via @c main. + * + * @param mt_level the required level of threading support + * + * @param abort_on_exception When true, this object will abort the + * program if it is destructed due to an uncaught exception. + */ + environment(int& argc, char** &argv, threading::level mt_level, + bool abort_on_exception = true); + /** Shuts down the MPI environment. * * If this @c environment object was used to initialize the MPI @@ -185,13 +257,21 @@ public: */ static std::string processor_name(); + /** Query the current level of thread support. + */ + static threading::level thread_level(); + + /** Are we in the main thread? + */ + static bool is_main_thread(); + private: /// Whether this environment object called MPI_Init bool i_initialized; /// Whether we should abort if the destructor is bool abort_on_exception; - + /// The number of reserved tags. static const int num_reserved_tags = 1; }; diff --git a/cpp/BoostParts/boost/mpi/inplace.hpp b/cpp/BoostParts/boost/mpi/inplace.hpp new file mode 100644 index 00000000..d84d07db --- /dev/null +++ b/cpp/BoostParts/boost/mpi/inplace.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2005-2006 Alain Miniussi . + +// Use, modification and distribution is subject to 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) + +// Message Passing Interface 1.1 -- Section 4. MPI Collectives + +/** @file inplace.hpp + * + * This header provides helpers to indicate to MPI collective operation + * that a buffer can be use both as an input and output. + */ +#ifndef BOOST_MPI_INPLACE_HPP +#define BOOST_MPI_INPLACE_HPP + +#include +#include + +namespace boost { namespace mpi { + +/** + * @brief Wrapper type to explicitly indicate that a input data + * can be overriden with an output value. + */ +template +struct inplace_t { + inplace_t(T& inout) : buffer(inout) {} + T& buffer; +}; + +template +struct inplace_t { + inplace_t(T* inout) : buffer(inout) {} + T* buffer; +}; + + +/** + * @brief Wrapp a input data to indicate that it can be overriden + * with an ouput value. + * @param inout the contributing input value, it will be overriden + * with the output value where one is expected. If it is a pointer, + * the number of elements will be provided separatly. + * @returns The wrapped value or pointer. + */ +template +inplace_t +inplace(T& inout) { + return inplace_t(inout); +} +/** + * \overload + */ +template +inplace_t +inplace(T* inout) { + return inplace_t(inout); +} +} } // end namespace boost::mpi + +#endif // BOOST_MPI_INPLACE_HPP + diff --git a/cpp/BoostParts/boost/mpi/packed_iarchive.hpp b/cpp/BoostParts/boost/mpi/packed_iarchive.hpp index c33e7f99..4610aa2f 100644 --- a/cpp/BoostParts/boost/mpi/packed_iarchive.hpp +++ b/cpp/BoostParts/boost/mpi/packed_iarchive.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,14 +38,16 @@ namespace boost { namespace mpi { typedef packed_iprimitive iprimitive; #endif -/** @brief An archive that packs binary data into an MPI buffer. + +/** @brief An archive that unpacks binary data from an MPI buffer. * - * The @c packed_iarchive class is an Archiver (as in the - * Boost.Serialization library) that packs binary data into a buffer - * for transmission via MPI. It can operate on any Serializable data - * type and will use the @c MPI_Pack function of the underlying MPI - * implementation to perform serialization. + * The @c packed_oarchive class is an Archiver (as in the + * Boost.Serialization library) that unpacks binary data from a + * buffer received via MPI. It can operate on any Serializable data + * type and will use the @c MPI_Unpack function of the underlying MPI + * implementation to perform deserialization. */ + class BOOST_MPI_DECL packed_iarchive : public iprimitive , public archive::detail::common_iarchive @@ -52,40 +55,37 @@ class BOOST_MPI_DECL packed_iarchive { public: /** - * Construct a @c packed_iarchive for transmission over the given + * Construct a @c packed_iarchive to receive data over the given * MPI communicator and with an initial buffer. * * @param comm The communicator over which this archive will be - * sent. + * received. * - * @param b A user-defined buffer that will be filled with the - * binary representation of serialized objects. + * @param b A user-defined buffer that contains the binary + * representation of serialized objects. * * @param flags Control the serialization of the data types. Refer * to the Boost.Serialization documentation before changing the * default flags. - * - * @param position Set the offset into buffer @p b at which - * deserialization will begin. */ + packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0) : iprimitive(b,comm,position), archive::detail::common_iarchive(flags) {} /** - * Construct a @c packed_iarchive for transmission over the given + * Construct a @c packed_iarchive to receive data over the given * MPI communicator. * * @param comm The communicator over which this archive will be - * sent. - * - * @param s The size of the buffer to be received. + * received. * * @param flags Control the serialization of the data types. Refer * to the Boost.Serialization documentation before changing the * default flags. */ + packed_iarchive ( MPI_Comm const & comm , std::size_t s=0, unsigned int flags = boost::archive::no_header) @@ -121,6 +121,16 @@ public: // input archives need to ignore the optional information void load_override(archive::class_id_optional_type & /*t*/, int){} + void load_override(archive::class_id_type & t, int version){ + int_least16_t x=0; + * this->This() >> x; + t = boost::archive::class_id_type(x); + } + + void load_override(archive::class_id_reference_type & t, int version){ + load_override(static_cast(t), version); + } + void load_override(archive::class_name_type & t, int) { std::string cn; diff --git a/cpp/BoostParts/boost/mpi/packed_oarchive.hpp b/cpp/BoostParts/boost/mpi/packed_oarchive.hpp index fb87e460..ec193df5 100644 --- a/cpp/BoostParts/boost/mpi/packed_oarchive.hpp +++ b/cpp/BoostParts/boost/mpi/packed_oarchive.hpp @@ -19,6 +19,7 @@ #define BOOST_MPI_PACKED_OARCHIVE_HPP #include +#include #include #include #include @@ -36,13 +37,13 @@ namespace boost { namespace mpi { typedef packed_oprimitive oprimitive; #endif -/** @brief An archive that unpacks binary data from an MPI buffer. +/** @brief An archive that packs binary data into an MPI buffer. * - * The @c packed_oarchive class is an Archiver (as in the - * Boost.Serialization library) that unpacks binary data from a - * buffer received via MPI. It can operate on any Serializable data - * type and will use the @c MPI_Unpack function of the underlying MPI - * implementation to perform deserialization. + * The @c packed_iarchive class is an Archiver (as in the + * Boost.Serialization library) that packs binary data into a buffer + * for transmission via MPI. It can operate on any Serializable data + * type and will use the @c MPI_Pack function of the underlying MPI + * implementation to perform serialization. */ class BOOST_MPI_DECL packed_oarchive @@ -52,35 +53,42 @@ class BOOST_MPI_DECL packed_oarchive { public: /** - * Construct a @c packed_oarchive to receive data over the given + * Construct a @c packed_oarchive for transmission over the given * MPI communicator and with an initial buffer. * * @param comm The communicator over which this archive will be - * received. + * sent. * - * @param b A user-defined buffer that contains the binary - * representation of serialized objects. + * @param b A user-defined buffer that will be filled with the + * binary representation of serialized objects. * * @param flags Control the serialization of the data types. Refer * to the Boost.Serialization documentation before changing the * default flags. + * + * @param position Set the offset into buffer @p b at which + * deserialization will begin. */ + packed_oarchive( MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header) : oprimitive(b,comm), archive::detail::common_oarchive(flags) {} /** - * Construct a @c packed_oarchive to receive data over the given + * Construct a @c packed_oarchive for transmission over the given * MPI communicator. * * @param comm The communicator over which this archive will be - * received. + * sent. + * + * @param s The size of the buffer to be received. * * @param flags Control the serialization of the data types. Refer * to the Boost.Serialization documentation before changing the * default flags. */ + packed_oarchive ( MPI_Comm const & comm, unsigned int flags = boost::archive::no_header) : oprimitive(internal_buffer_,comm), archive::detail::common_oarchive(flags) @@ -93,7 +101,7 @@ public: archive::detail::common_oarchive::save_override(x,version); } - // Save it directly using the primnivites + // Save it directly using the primitives template void save_override(T const& x, int /*version*/, mpl::true_) { @@ -117,6 +125,11 @@ public: * this->This() << s; } + void save_override(archive::class_id_type & t, int version){ + const boost::int_least16_t x = t; + * this->This() << x; + } + private: /// An internal buffer to be used when the user does not supply his /// own buffer. diff --git a/cpp/BoostParts/boost/mpl/assert.hpp b/cpp/BoostParts/boost/mpl/assert.hpp index a6f78a37..7a5818e9 100644 --- a/cpp/BoostParts/boost/mpl/assert.hpp +++ b/cpp/BoostParts/boost/mpl/assert.hpp @@ -10,9 +10,9 @@ // // See http://www.boost.org/libs/mpl for documentation. -// $Id: assert.hpp 84442 2013-05-23 14:38:22Z steven_watanabe $ -// $Date: 2013-05-23 07:38:22 -0700 (Thu, 23 May 2013) $ -// $Revision: 84442 $ +// $Id: assert.hpp 86514 2013-10-29 13:15:03Z bemandawes $ +// $Date: 2013-10-29 06:15:03 -0700 (Tue, 29 Oct 2013) $ +// $Revision: 86514 $ #include #include @@ -134,7 +134,7 @@ template< assert_::relations r, long x, long y > struct assert_relation {}; #endif -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1700) +#if BOOST_WORKAROUND(BOOST_MSVC, == 1700) template struct extract_assert_pred; diff --git a/cpp/BoostParts/boost/multi_index/detail/do_not_copy_elements_tag.hpp b/cpp/BoostParts/boost/multi_index/detail/do_not_copy_elements_tag.hpp new file mode 100644 index 00000000..a7b3f188 --- /dev/null +++ b/cpp/BoostParts/boost/multi_index/detail/do_not_copy_elements_tag.hpp @@ -0,0 +1,34 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Used to mark a special ctor variant that copies the internal objects of + * a container but not its elements. + */ + +struct do_not_copy_elements_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/cpp/BoostParts/boost/multi_index/detail/index_base.hpp b/cpp/BoostParts/boost/multi_index/detail/index_base.hpp index 9b73a4bb..a43214a7 100644 --- a/cpp/BoostParts/boost/multi_index/detail/index_base.hpp +++ b/cpp/BoostParts/boost/multi_index/detail/index_base.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2008 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -14,11 +14,15 @@ #endif #include /* keep it first to prevent nasty warns in MSVC */ -#include +#include #include +#include +#include #include #include +#include #include +#include #include #include #include @@ -42,6 +46,10 @@ namespace detail{ * cannot be called directly from the index classes.) */ +struct lvalue_tag{}; +struct rvalue_tag{}; +struct emplaced_tag{}; + template class index_base { @@ -74,27 +82,61 @@ protected: #endif private: - typedef typename call_traits::param_type value_param_type; + typedef Value value_type; protected: explicit index_base(const ctor_args_list&,const Allocator&){} + index_base( + const index_base&, + do_not_copy_elements_tag) + {} + void copy_( const index_base&,const copy_map_type&) {} - node_type* insert_(value_param_type v,node_type* x) + node_type* insert_(const value_type& v,node_type* x,lvalue_tag) { boost::detail::allocator::construct(&x->value(),v); return x; } - node_type* insert_(value_param_type v,node_type*,node_type* x) + node_type* insert_(const value_type& v,node_type* x,rvalue_tag) + { + /* This shoud have used a modified, T&&-compatible version of + * boost::detail::allocator::construct, but + * is too old and venerable to mess + * with; besides, it is a general internal utility and the imperfect + * perfect forwarding emulation of Boost.Move might break other libs. + */ + + new (&x->value()) value_type(boost::move(const_cast(v))); + return x; + } + + node_type* insert_(const value_type&,node_type* x,emplaced_tag) + { + return x; + } + + node_type* insert_(const value_type& v,node_type*,node_type* x,lvalue_tag) { boost::detail::allocator::construct(&x->value(),v); return x; } + node_type* insert_(const value_type& v,node_type*,node_type* x,rvalue_tag) + { + new (&x->value()) value_type(boost::move(const_cast(v))); + return x; + } + + node_type* insert_(const value_type&,node_type*,node_type* x,emplaced_tag) + { + return x; + } + void erase_(node_type* x) { boost::detail::allocator::destroy(&x->value()); @@ -109,12 +151,20 @@ protected: void swap_(index_base&){} - bool replace_(value_param_type v,node_type* x) + void swap_elements_(index_base&){} + + bool replace_(const value_type& v,node_type* x,lvalue_tag) { x->value()=v; return true; } + bool replace_(const value_type& v,node_type* x,rvalue_tag) + { + x->value()=boost::move(const_cast(v)); + return true; + } + bool modify_(node_type*){return true;} bool modify_rollback_(node_type*){return true;} @@ -146,11 +196,39 @@ protected: std::size_t final_size_()const{return final().size_();} std::size_t final_max_size_()const{return final().max_size_();} - std::pair final_insert_(value_param_type x) + std::pair final_insert_(const value_type& x) {return final().insert_(x);} + std::pair final_insert_rv_(const value_type& x) + {return final().insert_rv_(x);} + template + std::pair final_insert_ref_(T& t) + {return final().insert_ref_(t);} + + template + std::pair final_emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + std::pair final_insert_( - value_param_type x,final_node_type* position) + const value_type& x,final_node_type* position) {return final().insert_(x,position);} + std::pair final_insert_rv_( + const value_type& x,final_node_type* position) + {return final().insert_rv_(x,position);} + template + std::pair final_insert_ref_( + T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + + template + std::pair final_emplace_hint_( + final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_hint_( + position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } void final_erase_(final_node_type* x){final().erase_(x);} @@ -159,9 +237,13 @@ protected: void final_clear_(){final().clear_();} void final_swap_(final_type& x){final().swap_(x);} + bool final_replace_( - value_param_type k,final_node_type* x) + const value_type& k,final_node_type* x) {return final().replace_(k,x);} + bool final_replace_rv_( + const value_type& k,final_node_type* x) + {return final().replace_rv_(k,x);} template bool final_modify_(Modifier& mod,final_node_type* x) diff --git a/cpp/BoostParts/boost/multi_index/detail/scope_guard.hpp b/cpp/BoostParts/boost/multi_index/detail/scope_guard.hpp index 5640c8fb..c64429e5 100644 --- a/cpp/BoostParts/boost/multi_index/detail/scope_guard.hpp +++ b/cpp/BoostParts/boost/multi_index/detail/scope_guard.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2011 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -14,6 +14,7 @@ #endif #include +#include namespace boost{ diff --git a/cpp/BoostParts/boost/multi_index/detail/vartempl_support.hpp b/cpp/BoostParts/boost/multi_index/detail/vartempl_support.hpp new file mode 100644 index 00000000..f6db6bf2 --- /dev/null +++ b/cpp/BoostParts/boost/multi_index/detail/vartempl_support.hpp @@ -0,0 +1,247 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * 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) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP +#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +/* Utilities for emulation of variadic template functions. Variadic packs are + * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: + * + * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK + * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK + * - std::forward(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK + * + * Forwarding emulated with Boost.Move. A template functions foo_imp + * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS + * arguments: variable number of arguments is emulated by providing a set of + * overloads foo forwarding to foo_impl with + * + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) + * + * which fill the extra args with boost::multi_index::detail::noarg's. + * boost::multi_index::detail::vartempl_placement_new works the opposite + * way: it acceps a full a pointer x to Value and a + * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to + * new(x) Value(args) where args is the argument pack after discarding + * noarg's. + * + * Emulation decays to the real thing when the compiler supports variadic + * templates and move semantics natively. + */ + +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) +#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 +#endif + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) + +#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ +BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) + +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_ARG,~) + +#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ +boost::forward(BOOST_PP_CAT(t,n)) + +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) + +namespace boost{namespace multi_index{namespace detail{ +struct noarg{}; +}}} + +/* call vartempl function without args */ + +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) + +#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ +template + +#define BOOST_MULTI_INDEX_TEMPLATE_0(n) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_AND( \ + n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ + (ret)(name_from)(name_to)) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ + z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ + (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ +template< \ + typename Value \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n,typename T) \ +> \ +Value* name( \ + Value* x \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ +{ \ + return new(x) Value( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ +} + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ + name) + +BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) + +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +/* native variadic templates support */ + +#include + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward(args)... +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +template ret name_from(Args&&... args) \ +{ \ + return name_to(std::forward(args)...); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +template ret name_from( \ + extra_arg_type extra_arg_name,Args&&... args) \ +{ \ + return name_to(extra_arg_name,std::forward(args)...); \ +} + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +Value* vartempl_placement_new(Value*x,Args&&... args) +{ + return new(x) Value(std::forward(args)...); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/cpp/BoostParts/boost/multi_index/hashed_index.hpp b/cpp/BoostParts/boost/multi_index/hashed_index.hpp index 9d53bb81..ef02eb16 100644 --- a/cpp/BoostParts/boost/multi_index/hashed_index.hpp +++ b/cpp/BoostParts/boost/multi_index/hashed_index.hpp @@ -21,33 +21,43 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&hashed_index::check_invariant_); \ + detail::make_obj_guard(x,&hashed_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #endif @@ -191,6 +201,12 @@ private: typedef typename call_traits< key_type>::param_type key_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/destroy/copy @@ -205,6 +221,15 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + hashed_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + allocator_type get_allocator()const { return this->final().get_allocator(); @@ -248,14 +273,27 @@ public: /* modifiers */ - std::pair insert(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair p=this->final_insert_(x); return std::pair(make_iterator(p.first),p.second); } - iterator insert(iterator position,value_param_type x) + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -265,14 +303,30 @@ public: return make_iterator(p.first); } + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + template void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - iterator hint=end(); - for(;first!=last;++first)hint=insert(hint,*first); + for(;first!=last;++first)this->final_insert_ref_(*first); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -325,7 +379,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -335,6 +389,16 @@ public: x,static_cast(position.get_node())); } + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + template bool modify(iterator position,Modifier mod) { @@ -410,6 +474,7 @@ public: void swap(hashed_index& x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } @@ -634,6 +699,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: */ } + hashed_index( + const hashed_index& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),0), + mlf(1.0f), + first_bucket(buckets.size()) + { + calculate_max_load(); + } + ~hashed_index() { /* the container is guaranteed to be empty by now */ @@ -689,8 +773,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - - node_type* insert_(value_param_type v,node_type* x) + + template + node_type* insert_(value_param_type v,node_type* x,Variant variant) { reserve(size()+1); @@ -698,7 +783,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: node_impl_pointer pos=buckets.at(buc); if(!link_point(v,pos,Category()))return node_type::from_impl(pos); - node_type* res=static_cast(super::insert_(v,x)); + node_type* res=static_cast(super::insert_(v,x,variant)); if(res==x){ link(x,pos); if(first_bucket>buc)first_bucket=buc; @@ -706,7 +791,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template + node_type* insert_( + value_param_type v,node_type* position,node_type* x,Variant variant) { reserve(size()+1); @@ -714,7 +801,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: node_impl_pointer pos=buckets.at(buc); if(!link_point(v,pos,Category()))return node_type::from_impl(pos); - node_type* res=static_cast(super::insert_(v,position,x)); + node_type* res= + static_cast(super::insert_(v,position,x,variant)); if(res==x){ link(x,pos); if(first_bucket>buc)first_bucket=buc; @@ -776,10 +864,26 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_( + hashed_index& x) + { + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + std::swap(first_bucket,x.first_bucket); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) { if(eq_(key(v),key(x->value()))){ - return super::replace_(v,x); + return super::replace_(v,x,variant); } node_impl_pointer y=prev(x); @@ -788,7 +892,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: BOOST_TRY{ std::size_t buc=find_bucket(v); node_impl_pointer pos=buckets.at(buc); - if(link_point(v,pos,Category())&&super::replace_(v,x)){ + if(link_point(v,pos,Category())&&super::replace_(v,x,variant)){ link(x,pos); if(first_bucket>buc){ first_bucket=buc; @@ -1157,6 +1261,29 @@ private: } #endif + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + key_from_value key; hasher hash_; key_equal eq_; @@ -1257,5 +1384,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF #endif diff --git a/cpp/BoostParts/boost/multi_index/ordered_index.hpp b/cpp/BoostParts/boost/multi_index/ordered_index.hpp index e248a8b5..3dedbc14 100644 --- a/cpp/BoostParts/boost/multi_index/ordered_index.hpp +++ b/cpp/BoostParts/boost/multi_index/ordered_index.hpp @@ -47,11 +47,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -61,12 +63,17 @@ #include #include #include +#include #include #include #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #include @@ -75,11 +82,14 @@ #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&ordered_index::check_invariant_); \ + detail::make_obj_guard(x,&ordered_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT #endif @@ -217,6 +227,12 @@ private: typedef typename call_traits< key_type>::param_type key_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/copy/destroy @@ -231,6 +247,15 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + ordered_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + allocator_type get_allocator()const { return this->final().get_allocator(); @@ -269,14 +294,27 @@ public: /* modifiers */ - std::pair insert(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; std::pair p=this->final_insert_(x); return std::pair(make_iterator(p.first),p.second); } - iterator insert(iterator position,value_param_type x) + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -286,14 +324,35 @@ public: return make_iterator(p.first); } + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + template void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - iterator hint=end(); - for(;first!=last;++first)hint=insert(hint,*first); + node_type* hint=header(); /* end() */ + for(;first!=last;++first){ + hint=this->final_insert_ref_( + *first,static_cast(hint)).first; + node_type::increment(hint); + } } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -330,7 +389,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -340,6 +399,16 @@ public: x,static_cast(position.get_node())); } + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + template bool modify(iterator position,Modifier mod) { @@ -409,6 +478,7 @@ public: void swap(ordered_index& x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } @@ -551,10 +621,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: comp_(x.comp_) { /* Copy ctor just takes the key and compare objects from x. The rest is - * done in subsequent call to copy_(). + * done in a subsequent call to copy_(). */ } + ordered_index( + const ordered_index& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp_(x.comp_) + { + empty_initialize(); + } + ~ordered_index() { /* the container is guaranteed to be empty by now */ @@ -623,28 +708,31 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - node_type* insert_(value_param_type v,node_type* x) + template + node_type* insert_(value_param_type v,node_type* x,Variant variant) { link_info inf; if(!link_point(key(v),inf,Category())){ return node_type::from_impl(inf.pos); } - node_type* res=static_cast(super::insert_(v,x)); + node_type* res=static_cast(super::insert_(v,x,variant)); if(res==x){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); } return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template + node_type* insert_( + value_param_type v,node_type* position,node_type* x,Variant variant) { link_info inf; if(!hinted_link_point(key(v),position,inf,Category())){ return node_type::from_impl(inf.pos); } - node_type* res=static_cast(super::insert_(v,position,x)); + node_type* res=static_cast(super::insert_(v,position,x,variant)); if(res==x){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); } @@ -689,10 +777,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_( + ordered_index& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) { if(in_place(v,x,Category())){ - return super::replace_(v,x); + return super::replace_(v,x,variant); } node_type* next=x; @@ -703,7 +802,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: BOOST_TRY{ link_info inf; - if(link_point(key(v),inf,Category())&&super::replace_(v,x)){ + if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); return true; } @@ -1085,6 +1184,29 @@ private: } #endif + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + template std::pair range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const @@ -1402,5 +1524,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF #endif diff --git a/cpp/BoostParts/boost/multi_index/sequenced_index.hpp b/cpp/BoostParts/boost/multi_index/sequenced_index.hpp index e8832eee..7ea3c45e 100644 --- a/cpp/BoostParts/boost/multi_index/sequenced_index.hpp +++ b/cpp/BoostParts/boost/multi_index/sequenced_index.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2011 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -20,17 +20,21 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -38,16 +42,23 @@ #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \ + detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT #endif @@ -166,6 +177,12 @@ private: typedef typename call_traits::param_type value_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/copy/destroy @@ -180,12 +197,28 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + sequenced_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + template void assign(InputIterator first,InputIterator last) { assign_iter(first,last,mpl::not_ >()); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + void assign(size_type n,value_param_type value) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; @@ -231,22 +264,21 @@ public: size_type size()const{return this->final_size_();} size_type max_size()const{return this->final_max_size_();} - void resize(size_type n,value_param_type x=value_type()) + void resize(size_type n) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(n>size()){ + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + } + else if(nsize())insert(end(),n-size(),x); - else if(n push_front(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_front,emplace_front_impl) + + std::pair push_front(const value_type& x) {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} void pop_front(){erase(begin());} - std::pair push_back(value_param_type x) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} void pop_back(){erase(--end());} - std::pair insert(iterator position,value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -277,6 +323,18 @@ public: return std::pair(make_iterator(p.first),p.second); } + std::pair insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + void insert(iterator position,size_type n,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -291,6 +349,13 @@ public: insert_iter(position,first,last,mpl::not_ >()); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(iterator position,std::initializer_list list) + { + insert(position,list.begin(),list.end()); + } +#endif + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -315,7 +380,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -325,6 +390,16 @@ public: x,static_cast(position.get_node())); } + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + template bool modify(iterator position,Modifier mod) { @@ -370,6 +445,7 @@ public: void swap(sequenced_index& x) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } @@ -555,8 +631,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: #endif { - /* The actual copying takes place in subsequent call to copy_(). - */ + /* the actual copying takes place in subsequent call to copy_() */ + } + + sequenced_index( + const sequenced_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()) + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,safe_super() +#endif + + { + empty_initialize(); } ~sequenced_index() @@ -591,16 +678,20 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - node_type* insert_(value_param_type v,node_type* x) + template + node_type* insert_(value_param_type v,node_type* x,Variant variant) { - node_type* res=static_cast(super::insert_(v,x)); + node_type* res=static_cast(super::insert_(v,x,variant)); if(res==x)link(x); return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template + node_type* insert_( + value_param_type v,node_type* position,node_type* x,Variant variant) { - node_type* res=static_cast(super::insert_(v,position,x)); + node_type* res= + static_cast(super::insert_(v,position,x,variant)); if(res==x)link(x); return res; } @@ -643,9 +734,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_(sequenced_index& x) { - return super::replace_(v,x); +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); } bool modify_(node_type* x) @@ -781,7 +882,7 @@ private: { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); - for(;first!=last;++first)push_back(*first); + for(;first!=last;++first)this->final_insert_ref_(*first); } void assign_iter(size_type n,value_param_type value,mpl::false_) @@ -796,7 +897,13 @@ private: iterator position,InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(;first!=last;++first)insert(position,*first); + for(;first!=last;++first){ + std::pair p= + this->final_insert_ref_(*first); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + } } void insert_iter( @@ -807,7 +914,36 @@ private: BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; for(size_type i=0;i + std::pair emplace_front_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_back_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) #pragma parse_mfunc_templ reset @@ -929,5 +1065,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF #endif diff --git a/cpp/BoostParts/boost/multi_index_container.hpp b/cpp/BoostParts/boost/multi_index_container.hpp index 2a2209fd..e06d2cb5 100644 --- a/cpp/BoostParts/boost/multi_index_container.hpp +++ b/cpp/BoostParts/boost/multi_index_container.hpp @@ -1,6 +1,6 @@ /* Multiply indexed container. * - * Copyright 2003-2011 Joaquin M Lopez Munoz. + * Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -38,10 +40,15 @@ #include #include #include +#include #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #include @@ -54,11 +61,14 @@ #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #include -#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \ + detail::make_obj_guard(x,&multi_index_container::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_CHECK_INVARIANT #endif @@ -66,6 +76,11 @@ namespace boost{ namespace multi_index{ +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(push) +#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */ +#endif + template class multi_index_container: private ::boost::base_from_member< @@ -98,6 +113,8 @@ class multi_index_container: #endif private: + BOOST_COPYABLE_AND_MOVABLE(multi_index_container) + #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template friend class detail::index_base; template friend struct detail::header_holder; @@ -194,7 +211,7 @@ public: node_count(0) { BOOST_MULTI_INDEX_CHECK_INVARIANT; - } + } explicit multi_index_container(const allocator_type& al): bfm_allocator(al), @@ -203,7 +220,7 @@ public: { BOOST_MULTI_INDEX_CHECK_INVARIANT; } - + template multi_index_container( InputIterator first,InputIterator last, @@ -232,7 +249,9 @@ public: BOOST_TRY{ iterator hint=super::end(); for(;first!=last;++first){ - hint=super::make_iterator(insert_(*first,hint.get_node()).first); + hint=super::make_iterator( + insert_ref_(*first,hint.get_node()).first); + ++hint; } } BOOST_CATCH(...){ @@ -242,6 +261,34 @@ public: BOOST_CATCH_END } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + std::initializer_list list, + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_TRY{ + typedef typename std::initializer_list::iterator init_iterator; + + iterator hint=super::end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=super::make_iterator(insert_(*first,hint.get_node()).first); + ++hint; + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } +#endif + multi_index_container( const multi_index_container& x): bfm_allocator(x.bfm_allocator::member), @@ -264,19 +311,70 @@ public: BOOST_MULTI_INDEX_CHECK_INVARIANT; } + multi_index_container(BOOST_RV_REF(multi_index_container) x): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); + swap_elements_(x); + } + ~multi_index_container() { delete_all_nodes_(); } +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /* As per http://www.boost.org/doc/html/move/emulation_limitations.html + * #move.emulation_limitations.assignment_operator + */ + multi_index_container& operator=( - multi_index_container x) + const multi_index_container& x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } +#endif + + multi_index_container& operator=( + BOOST_COPY_ASSIGN_REF(multi_index_container) x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } + + multi_index_container& operator=( + BOOST_RV_REF(multi_index_container) x) { - BOOST_MULTI_INDEX_CHECK_INVARIANT; this->swap(x); return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container& operator=( + std::initializer_list list) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + typedef typename std::initializer_list::iterator init_iterator; + + multi_index_container x(*this,detail::do_not_copy_elements_tag()); + iterator hint=x.end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=x.make_iterator(x.insert_(*first,hint.get_node()).first); + ++hint; + } + x.swap_elements_(*this); + return*this; + } +#endif + allocator_type get_allocator()const { return allocator_type(bfm_allocator::member); @@ -450,6 +548,19 @@ public: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: typedef typename super::copy_map_type copy_map_type; +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + const multi_index_container& x, + detail::do_not_copy_elements_tag): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } +#endif + node_type* header()const { return &*bfm_header::member; @@ -481,11 +592,119 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: return static_cast(-1); } - std::pair insert_(const Value& v) + template + std::pair insert_(const Value& v,Variant variant) { node_type* x=allocate_node(); BOOST_TRY{ - node_type* res=super::insert_(v,x); + node_type* res=super::insert_(v,x,variant); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_(const Value& v) + { + return insert_(v,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v) + { + return insert_(v,detail::rvalue_tag()); + } + + template + std::pair insert_ref_(T& t) + { + node_type* x=allocate_node(); + BOOST_TRY{ + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_(const value_type& x) + { + return insert_(x); + } + + std::pair insert_ref_(value_type& x) + { + return insert_(x); + } + + template + std::pair emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template + std::pair insert_( + const Value& v,node_type* position,Variant variant) + { + node_type* x=allocate_node(); + BOOST_TRY{ + node_type* res=super::insert_(v,position,x,variant); if(res==x){ ++node_count; return std::pair(res,true); @@ -503,18 +722,87 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: } std::pair insert_(const Value& v,node_type* position) + { + return insert_(v,position,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v,node_type* position) + { + return insert_(v,position,detail::rvalue_tag()); + } + + template + std::pair insert_ref_( + T& t,node_type* position) { node_type* x=allocate_node(); BOOST_TRY{ - node_type* res=super::insert_(v,position,x); - if(res==x){ - ++node_count; - return std::pair(res,true); + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } } - else{ - deallocate_node(x); - return std::pair(res,false); + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_( + const value_type& x,node_type* position) + { + return insert_(x,position); + } + + std::pair insert_ref_( + value_type& x,node_type* position) + { + return insert_(x,position); + } + + template + std::pair emplace_hint_( + node_type* position, + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END } BOOST_CATCH(...){ deallocate_node(x); @@ -558,9 +846,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: std::swap(node_count,x.node_count); } + void swap_elements_( + multi_index_container& x) + { + std::swap(bfm_header::member,x.bfm_header::member); + super::swap_elements_(x); + std::swap(node_count,x.node_count); + } + bool replace_(const Value& k,node_type* x) { - return super::replace_(k,x); + return super::replace_(k,x,detail::lvalue_tag()); + } + + bool replace_rv_(const Value& k,node_type* x) + { + return super::replace_(k,x,detail::rvalue_tag()); } template @@ -728,6 +1029,10 @@ private: #endif }; +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(pop) /* C4522 */ +#endif + /* retrieval of indices by number */ template @@ -1139,5 +1444,6 @@ using multi_index::project; } /* namespace boost */ #undef BOOST_MULTI_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF #endif diff --git a/cpp/BoostParts/boost/predef/architecture.h b/cpp/BoostParts/boost/predef/architecture.h new file mode 100644 index 00000000..9eda25e1 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture.h @@ -0,0 +1,30 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_H +#define BOOST_PREDEF_ARCHITECTURE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*#include */ + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/alpha.h b/cpp/BoostParts/boost/predef/architecture/alpha.h new file mode 100644 index 00000000..7ccc480a --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/alpha.h @@ -0,0 +1,60 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ALPHA_H +#define BOOST_PREDEF_ARCHITECTURE_ALPHA_H + +#include +#include + +/*` +[heading `BOOST_ARCH_ALPHA`] + +[@http://en.wikipedia.org/wiki/DEC_Alpha DEC Alpha] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + [[`__alpha__`] [__predef_detection__]] + [[`__alpha`] [__predef_detection__]] + [[`_M_ALPHA`] [__predef_detection__]] + + [[`__alpha_ev4__`] [4.0.0]] + [[`__alpha_ev5__`] [5.0.0]] + [[`__alpha_ev6__`] [6.0.0]] + ] + */ + +#define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__alpha__) || defined(__alpha) || \ + defined(_M_ALPHA) +# undef BOOST_ARCH_ALPHA +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev4__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev5__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev6__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ALPHA +# define BOOST_ARCH_ALPHA_AVAILABLE +#endif + +#define BOOST_ARCH_ALPHA_NAME "DEC Alpha" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ALPHA,BOOST_ARCH_ALPHA_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/arm.h b/cpp/BoostParts/boost/predef/architecture/arm.h new file mode 100644 index 00000000..b221a510 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/arm.h @@ -0,0 +1,58 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ARM_H +#define BOOST_PREDEF_ARCHITECTURE_ARM_H + +#include +#include + +/*` +[heading `BOOST_ARCH_ARM`] + +[@http://en.wikipedia.org/wiki/ARM_architecture ARM] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__arm__`] [__predef_detection__]] + [[`__thumb__`] [__predef_detection__]] + [[`__TARGET_ARCH_ARM`] [__predef_detection__]] + [[`__TARGET_ARCH_THUMB`] [__predef_detection__]] + + [[`__TARGET_ARCH_ARM`] [V.0.0]] + [[`__TARGET_ARCH_THUMB`] [V.0.0]] + ] + */ + +#define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__arm__) || defined(__thumb__) || \ + defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) +# undef BOOST_ARCH_ARM +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_ARM,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_THUMB) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_THUMB,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ARM +# define BOOST_ARCH_ARM_AVAILABLE +#endif + +#define BOOST_ARCH_ARM_NAME "ARM" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ARM,BOOST_ARCH_ARM_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/blackfin.h b/cpp/BoostParts/boost/predef/architecture/blackfin.h new file mode 100644 index 00000000..7b4f2758 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/blackfin.h @@ -0,0 +1,47 @@ +/* +Copyright Redshift Software Inc 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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H +#define BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H + +#include +#include + +/*` +[heading `BOOST_ARCH_BLACKFIN`] + +Blackfin Processors from Analog Devices. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__bfin__`] [__predef_detection__]] + [[`__BFIN__`] [__predef_detection__]] + [[`bfin`] [__predef_detection__]] + [[`BFIN`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__bfin__) || defined(__BFIN__) || \ + defined(bfin) || defined(BFIN) +# undef BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN_AVAILABLE +#endif + +#define BOOST_ARCH_BLACKFIN_NAME "Blackfin" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_BLACKFIN,BOOST_ARCH_BLACKFIN_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/convex.h b/cpp/BoostParts/boost/predef/architecture/convex.h new file mode 100644 index 00000000..fbb8e965 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/convex.h @@ -0,0 +1,67 @@ +/* +Copyright Redshift Software Inc 2011-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_CONVEX_H +#define BOOST_PREDEF_ARCHITECTURE_CONVEX_H + +#include +#include + +/*` +[heading `BOOST_ARCH_CONVEX`] + +[@http://en.wikipedia.org/wiki/Convex_Computer Convex Computer] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__convex__`] [__predef_detection__]] + + [[`__convex_c1__`] [1.0.0]] + [[`__convex_c2__`] [2.0.0]] + [[`__convex_c32__`] [3.2.0]] + [[`__convex_c34__`] [3.4.0]] + [[`__convex_c38__`] [3.8.0]] + ] + */ + +#define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__convex__) +# undef BOOST_ARCH_CONVEX +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c1__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c2__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c32__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c34__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c38__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_CONVEX +# define BOOST_ARCH_CONVEX_AVAILABLE +#endif + +#define BOOST_ARCH_CONVEX_NAME "Convex Computer" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_CONVEX,BOOST_ARCH_CONVEX_NAME) + + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/ia64.h b/cpp/BoostParts/boost/predef/architecture/ia64.h new file mode 100644 index 00000000..918e27f0 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/ia64.h @@ -0,0 +1,49 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_IA64_H +#define BOOST_PREDEF_ARCHITECTURE_IA64_H + +#include +#include + +/*` +[heading `BOOST_ARCH_IA64`] + +[@http://en.wikipedia.org/wiki/Ia64 Intel Itanium 64] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__ia64__`] [__predef_detection__]] + [[`_IA64`] [__predef_detection__]] + [[`__IA64__`] [__predef_detection__]] + [[`__ia64`] [__predef_detection__]] + [[`_M_IA64`] [__predef_detection__]] + [[`__itanium__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ia64__) || defined(_IA64) || \ + defined(__IA64__) || defined(__ia64) || \ + defined(_M_IA64) || defined(__itanium__) +# undef BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64_AVAILABLE +#endif + +#define BOOST_ARCH_IA64_NAME "Intel Itanium 64" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_IA64,BOOST_ARCH_IA64_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/m68k.h b/cpp/BoostParts/boost/predef/architecture/m68k.h new file mode 100644 index 00000000..2950c9a1 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/m68k.h @@ -0,0 +1,83 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_M68K_H +#define BOOST_PREDEF_ARCHITECTURE_M68K_H + +#include +#include + +/*` +[heading `BOOST_ARCH_M68K`] + +[@http://en.wikipedia.org/wiki/M68k Motorola 68k] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__m68k__`] [__predef_detection__]] + [[`M68000`] [__predef_detection__]] + + [[`__mc68060__`] [6.0.0]] + [[`mc68060`] [6.0.0]] + [[`__mc68060`] [6.0.0]] + [[`__mc68040__`] [4.0.0]] + [[`mc68040`] [4.0.0]] + [[`__mc68040`] [4.0.0]] + [[`__mc68030__`] [3.0.0]] + [[`mc68030`] [3.0.0]] + [[`__mc68030`] [3.0.0]] + [[`__mc68020__`] [2.0.0]] + [[`mc68020`] [2.0.0]] + [[`__mc68020`] [2.0.0]] + [[`__mc68010__`] [1.0.0]] + [[`mc68010`] [1.0.0]] + [[`__mc68010`] [1.0.0]] + [[`__mc68000__`] [0.0.1]] + [[`mc68000`] [0.0.1]] + [[`__mc68000`] [0.0.1]] + ] + */ + +#define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__m68k__) || defined(M68000) +# undef BOOST_ARCH_M68K +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68060__) || defined(mc68060) || defined(__mc68060)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68040__) || defined(mc68040) || defined(__mc68040)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68030__) || defined(mc68030) || defined(__mc68030)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68020__) || defined(mc68020) || defined(__mc68020)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68010__) || defined(mc68010) || defined(__mc68010)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68000__) || defined(mc68000) || defined(__mc68000)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if !defined(BOOST_ARCH_M68K) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_M68K +# define BOOST_ARCH_M68K_AVAILABLE +#endif + +#define BOOST_ARCH_M68K_NAME "Motorola 68k" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_M68K,BOOST_ARCH_M68K_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/mips.h b/cpp/BoostParts/boost/predef/architecture/mips.h new file mode 100644 index 00000000..b3d225cb --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/mips.h @@ -0,0 +1,74 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_MIPS_H +#define BOOST_PREDEF_ARCHITECTURE_MIPS_H + +#include +#include + +/*` +[heading `BOOST_ARCH_MIPS`] + +[@http://en.wikipedia.org/wiki/MIPS_architecture MIPS] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__mips__`] [__predef_detection__]] + [[`__mips`] [__predef_detection__]] + [[`__MIPS__`] [__predef_detection__]] + + [[`__mips`] [V.0.0]] + [[`_MIPS_ISA_MIPS1`] [1.0.0]] + [[`_R3000`] [1.0.0]] + [[`_MIPS_ISA_MIPS2`] [2.0.0]] + [[`__MIPS_ISA2__`] [2.0.0]] + [[`_R4000`] [2.0.0]] + [[`_MIPS_ISA_MIPS3`] [3.0.0]] + [[`__MIPS_ISA3__`] [3.0.0]] + [[`_MIPS_ISA_MIPS4`] [4.0.0]] + [[`__MIPS_ISA4__`] [4.0.0]] + ] + */ + +#define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__mips__) || defined(__mips) || \ + defined(__MIPS__) +# undef BOOST_ARCH_MIPS +# if !defined(BOOST_ARCH_MIPS) && (defined(__mips)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(__mips,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS1) || defined(_R3000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS2) || defined(__MIPS_ISA2__) || defined(_R4000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS3) || defined(__MIPS_ISA3__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS4) || defined(__MIPS_ISA4__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_MIPS +# define BOOST_ARCH_MIPS_AVAILABLE +#endif + +#define BOOST_ARCH_MIPS_NAME "MIPS" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_MIPS,BOOST_ARCH_MIPS_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/parisc.h b/cpp/BoostParts/boost/predef/architecture/parisc.h new file mode 100644 index 00000000..73703832 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/parisc.h @@ -0,0 +1,65 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PARISC_H +#define BOOST_PREDEF_ARCHITECTURE_PARISC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PARISK`] + +[@http://en.wikipedia.org/wiki/PA-RISC_family HP/PA RISC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__hppa__`] [__predef_detection__]] + [[`__hppa`] [__predef_detection__]] + [[`__HPPA__`] [__predef_detection__]] + + [[`_PA_RISC1_0`] [1.0.0]] + [[`_PA_RISC1_1`] [1.1.0]] + [[`__HPPA11__`] [1.1.0]] + [[`__PA7100__`] [1.1.0]] + [[`_PA_RISC2_0`] [2.0.0]] + [[`__RISC2_0__`] [2.0.0]] + [[`__HPPA20__`] [2.0.0]] + [[`__PA8000__`] [2.0.0]] + ] + */ + +#define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__hppa__) || defined(__hppa) || defined(__HPPA__) +# undef BOOST_ARCH_PARISC +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_0)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_1) || defined(__HPPA11__) || defined(__PA7100__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,1,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC2_0) || defined(__RISC2_0__) || defined(__HPPA20__) || defined(__PA8000__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PARISC +# define BOOST_ARCH_PARISC_AVAILABLE +#endif + +#define BOOST_ARCH_PARISC_NAME "HP/PA RISC" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PARISC,BOOST_ARCH_PARISC_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/ppc.h b/cpp/BoostParts/boost/predef/architecture/ppc.h new file mode 100644 index 00000000..8339ed24 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/ppc.h @@ -0,0 +1,73 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PPC_H +#define BOOST_PREDEF_ARCHITECTURE_PPC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PPC`] + +[@http://en.wikipedia.org/wiki/PowerPC PowerPC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__powerpc`] [__predef_detection__]] + [[`__powerpc__`] [__predef_detection__]] + [[`__POWERPC__`] [__predef_detection__]] + [[`__ppc__`] [__predef_detection__]] + [[`_M_PPC`] [__predef_detection__]] + [[`_ARCH_PPC`] [__predef_detection__]] + [[`__PPCGECKO__`] [__predef_detection__]] + [[`__PPCBROADWAY__`] [__predef_detection__]] + [[`_XENON`] [__predef_detection__]] + + [[`__ppc601__`] [6.1.0]] + [[`_ARCH_601`] [6.1.0]] + [[`__ppc603__`] [6.3.0]] + [[`_ARCH_603`] [6.3.0]] + [[`__ppc604__`] [6.4.0]] + [[`__ppc604__`] [6.4.0]] + ] + */ + +#define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__powerpc) || defined(__powerpc__) || \ + defined(__POWERPC__) || defined(__ppc__) || \ + defined(_M_PPC) || defined(_ARCH_PPC) || \ + defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ + defined(_XENON) +# undef BOOST_ARCH_PPC +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc601__) || defined(_ARCH_601)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,1,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc603__) || defined(_ARCH_603)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,3,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc604__) || defined(__ppc604__)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,4,0) +# endif +# if !defined (BOOST_ARCH_PPC) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PPC +# define BOOST_ARCH_PPC_AVAILABLE +#endif + +#define BOOST_ARCH_PPC_NAME "PowerPC" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/pyramid.h b/cpp/BoostParts/boost/predef/architecture/pyramid.h new file mode 100644 index 00000000..706e0cda --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/pyramid.h @@ -0,0 +1,43 @@ +/* +Copyright Redshift Software Inc 2011-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PYRAMID_H +#define BOOST_PREDEF_ARCHITECTURE_PYRAMID_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PYRAMID`] + +Pyramid 9810 architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`pyr`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(pyr) +# undef BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID_AVAILABLE +#endif + +#define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PYRAMID,BOOST_ARCH_PYRAMID_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/rs6k.h b/cpp/BoostParts/boost/predef/architecture/rs6k.h new file mode 100644 index 00000000..c05fefd1 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/rs6k.h @@ -0,0 +1,56 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_RS6K_H +#define BOOST_PREDEF_ARCHITECTURE_RS6K_H + +#include +#include + +/*` +[heading `BOOST_ARCH_RS6000`] + +[@http://en.wikipedia.org/wiki/RS/6000 RS/6000] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__THW_RS6000`] [__predef_detection__]] + [[`_IBMR2`] [__predef_detection__]] + [[`_POWER`] [__predef_detection__]] + [[`_ARCH_PWR`] [__predef_detection__]] + [[`_ARCH_PWR2`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__THW_RS6000) || defined(_IBMR2) || \ + defined(_POWER) || defined(_ARCH_PWR) || \ + defined(_ARCH_PWR2) +# undef BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000_AVAILABLE +#endif + +#define BOOST_ARCH_RS6000_NAME "RS/6000" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME) + +#define BOOST_ARCH_PWR BOOST_ARCH_RS6000 + +#if BOOST_ARCH_PWR +# define BOOST_ARCH_PWR_AVAILABLE +#endif + +#define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/sparc.h b/cpp/BoostParts/boost/predef/architecture/sparc.h new file mode 100644 index 00000000..30207a05 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/sparc.h @@ -0,0 +1,55 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SPARC_H +#define BOOST_PREDEF_ARCHITECTURE_SPARC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SPARC`] + +[@http://en.wikipedia.org/wiki/SPARC SPARC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sparc__`] [__predef_detection__]] + [[`__sparc`] [__predef_detection__]] + + [[`__sparcv9`] [9.0.0]] + [[`__sparcv8`] [8.0.0]] + ] + */ + +#define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sparc__) || defined(__sparc) +# undef BOOST_ARCH_SPARC +# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv9) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv8) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) && +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SPARC +# define BOOST_ARCH_SPARC_AVAILABLE +#endif + +#define BOOST_ARCH_SPARC_NAME "SPARC" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SPARC,BOOST_ARCH_SPARC_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/superh.h b/cpp/BoostParts/boost/predef/architecture/superh.h new file mode 100644 index 00000000..f87f4927 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/superh.h @@ -0,0 +1,68 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SUPERH_H +#define BOOST_PREDEF_ARCHITECTURE_SUPERH_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SH`] + +[@http://en.wikipedia.org/wiki/SuperH SuperH] architecture: +If available versions \[1-5\] are specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sh__`] [__predef_detection__]] + + [[`__SH5__`] [5.0.0]] + [[`__SH4__`] [4.0.0]] + [[`__sh3__`] [3.0.0]] + [[`__SH3__`] [3.0.0]] + [[`__sh2__`] [2.0.0]] + [[`__sh1__`] [1.0.0]] + ] + */ + +#define BOOST_ARCH_SH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sh__) +# undef BOOST_ARCH_SH +# if !defined(BOOST_ARCH_SH) && (defined(__SH5__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__SH4__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh3__) || defined(__SH3__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh2__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh1__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_SH) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SH +# define BOOST_ARCH_SH_AVAILABLE +#endif + +#define BOOST_ARCH_SH_NAME "SuperH" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SH,BOOST_ARCH_SH_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/sys370.h b/cpp/BoostParts/boost/predef/architecture/sys370.h new file mode 100644 index 00000000..f2fba780 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/sys370.h @@ -0,0 +1,44 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS370_H +#define BOOST_PREDEF_ARCHITECTURE_SYS370_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SYS370`] + +[@http://en.wikipedia.org/wiki/System/370 System/370] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__370__`] [__predef_detection__]] + [[`__THW_370__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__370__) || defined(__THW_370__) +# undef BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370_AVAILABLE +#endif + +#define BOOST_ARCH_SYS370_NAME "System/370" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS370,BOOST_ARCH_SYS370_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/sys390.h b/cpp/BoostParts/boost/predef/architecture/sys390.h new file mode 100644 index 00000000..a9e03d9b --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/sys390.h @@ -0,0 +1,44 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS390_H +#define BOOST_PREDEF_ARCHITECTURE_SYS390_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SYS390`] + +[@http://en.wikipedia.org/wiki/System/390 System/390] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__s390__`] [__predef_detection__]] + [[`__s390x__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__s390__) || defined(__s390x__) +# undef BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390_AVAILABLE +#endif + +#define BOOST_ARCH_SYS390_NAME "System/390" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS390,BOOST_ARCH_SYS390_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/x86.h b/cpp/BoostParts/boost/predef/architecture/x86.h new file mode 100644 index 00000000..3a08e9c1 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/x86.h @@ -0,0 +1,38 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H +#define BOOST_PREDEF_ARCHITECTURE_X86_H + +#include +#include + +/*` +[heading `BOOST_ARCH_X86`] + +[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture. This is +a category to indicate that either `BOOST_ARCH_X86_32` or +`BOOST_ARCH_X86_64` is detected. + */ + +#define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_ARCH_X86_32 || BOOST_ARCH_X86_64 +# undef BOOST_ARCH_X86 +# define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86 +# define BOOST_ARCH_X86_AVAILABLE +#endif + +#define BOOST_ARCH_X86_NAME "Intel x86" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86,BOOST_ARCH_X86_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/x86/32.h b/cpp/BoostParts/boost/predef/architecture/x86/32.h new file mode 100644 index 00000000..131d94d3 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/x86/32.h @@ -0,0 +1,87 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_32_H +#define BOOST_PREDEF_ARCHITECTURE_X86_32_H + +#include +#include + +/*` +[heading `BOOST_ARCH_X86_32`] + +[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture: +If available versions \[3-6\] are specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`i386`] [__predef_detection__]] + [[`__i386__`] [__predef_detection__]] + [[`__i486__`] [__predef_detection__]] + [[`__i586__`] [__predef_detection__]] + [[`__i686__`] [__predef_detection__]] + [[`__i386`] [__predef_detection__]] + [[`_M_IX86`] [__predef_detection__]] + [[`_X86_`] [__predef_detection__]] + [[`__THW_INTEL__`] [__predef_detection__]] + [[`__I86__`] [__predef_detection__]] + [[`__INTEL__`] [__predef_detection__]] + + [[`__I86__`] [V.0.0]] + [[`_M_IX86`] [V.0.0]] + [[`__i686__`] [6.0.0]] + [[`__i586__`] [5.0.0]] + [[`__i486__`] [4.0.0]] + [[`__i386__`] [3.0.0]] + ] + */ + +#define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(i386) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__i386) || \ + defined(_M_IX86) || defined(_X86_) || \ + defined(__THW_INTEL__) || defined(__I86__) || \ + defined(__INTEL__) +# undef BOOST_ARCH_X86_32 +# if !defined(BOOST_ARCH_X86_32) && defined(__I86__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(__I86__,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(_M_IX86) +# define BOOST_ARCH_X86_32 BOOST_PREDEF_MAKE_10_VV00(_M_IX86) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i686__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i586__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i486__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i386__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_X86_32 +# define BOOST_ARCH_X86_32_AVAILABLE +#endif + +#define BOOST_ARCH_X86_32_NAME "Intel x86-32" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME) + +#include + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/x86/64.h b/cpp/BoostParts/boost/predef/architecture/x86/64.h new file mode 100644 index 00000000..0bee9c96 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/x86/64.h @@ -0,0 +1,50 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_64_H +#define BOOST_PREDEF_ARCHITECTURE_X86_64_H + +#include +#include + +/*` +[heading `BOOST_ARCH_X86_64`] + +[@http://en.wikipedia.org/wiki/Ia64 Intel IA-64] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__x86_64`] [__predef_detection__]] + [[`__x86_64__`] [__predef_detection__]] + [[`__amd64__`] [__predef_detection__]] + [[`__amd64`] [__predef_detection__]] + [[`_M_X64`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__amd64__) || defined(__amd64) || \ + defined(_M_X64) +# undef BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64_AVAILABLE +#endif + +#define BOOST_ARCH_X86_64_NAME "Intel x86-64" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME) + +#include + +#endif diff --git a/cpp/BoostParts/boost/predef/architecture/z.h b/cpp/BoostParts/boost/predef/architecture/z.h new file mode 100644 index 00000000..622d6ab3 --- /dev/null +++ b/cpp/BoostParts/boost/predef/architecture/z.h @@ -0,0 +1,43 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_Z_H +#define BOOST_PREDEF_ARCHITECTURE_Z_H + +#include +#include + +/*` +[heading `BOOST_ARCH_Z`] + +[@http://en.wikipedia.org/wiki/Z/Architecture z/Architecture] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__SYSC_ZARCH__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_Z BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SYSC_ZARCH__) +# undef BOOST_ARCH_Z +# define BOOST_ARCH_Z BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_Z +# define BOOST_ARCH_Z_AVAILABLE +#endif + +#define BOOST_ARCH_Z_NAME "z/Architecture" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_Z,BOOST_ARCH_Z_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/detail/_cassert.h b/cpp/BoostParts/boost/predef/detail/_cassert.h new file mode 100644 index 00000000..ca594a84 --- /dev/null +++ b/cpp/BoostParts/boost/predef/detail/_cassert.h @@ -0,0 +1,17 @@ +/* +Copyright Redshift Software, Inc. 2011-2012 +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_PREDEF_DETAIL__CASSERT_H +#define BOOST_PREDEF_DETAIL__CASSERT_H + +#if defined(__cpluplus) +#include +#else +#include +#endif + +#endif diff --git a/cpp/BoostParts/boost/predef/detail/endian_compat.h b/cpp/BoostParts/boost/predef/detail/endian_compat.h new file mode 100644 index 00000000..b8736597 --- /dev/null +++ b/cpp/BoostParts/boost/predef/detail/endian_compat.h @@ -0,0 +1,26 @@ +/* +Copyright Redshift Software, Inc. 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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_ENDIAN_COMPAT_H +#define BOOST_PREDEF_DETAIL_ENDIAN_COMPAT_H + +#include + +#if BOOST_ENDIAN_BIG_BYTE +# define BOOST_BIG_ENDIAN +# define BOOST_BYTE_ORDER 4321 +#endif +#if BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_LITTLE_ENDIAN +# define BOOST_BYTE_ORDER 1234 +#endif +#if BOOST_ENDIAN_LITTLE_WORD +# define BOOST_PDP_ENDIAN +# define BOOST_BYTE_ORDER 2134 +#endif + +#endif diff --git a/cpp/BoostParts/boost/predef/detail/os_detected.h b/cpp/BoostParts/boost/predef/detail/os_detected.h new file mode 100644 index 00000000..7d70c1ef --- /dev/null +++ b/cpp/BoostParts/boost/predef/detail/os_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Redshift Software, Inc. 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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_OS_DETECTED +#define BOOST_PREDEF_DETAIL_OS_DETECTED 1 +#endif diff --git a/cpp/BoostParts/boost/predef/detail/test.h b/cpp/BoostParts/boost/predef/detail/test.h new file mode 100644 index 00000000..c75eccc5 --- /dev/null +++ b/cpp/BoostParts/boost/predef/detail/test.h @@ -0,0 +1,17 @@ +/* +Copyright Redshift Software Inc. 2011-2012 +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_PREDEF_DETAIL_TEST_H +#define BOOST_PREDEF_DETAIL_TEST_H + +#if !defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) + +#define BOOST_PREDEF_DECLARE_TEST(x,s) + +#endif + +#endif diff --git a/cpp/BoostParts/boost/predef/library/c/_prefix.h b/cpp/BoostParts/boost/predef/library/c/_prefix.h new file mode 100644 index 00000000..754601f5 --- /dev/null +++ b/cpp/BoostParts/boost/predef/library/c/_prefix.h @@ -0,0 +1,13 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C__PREFIX_H +#define BOOST_PREDEF_LIBRARY_C__PREFIX_H + +#include + +#endif diff --git a/cpp/BoostParts/boost/predef/library/c/gnu.h b/cpp/BoostParts/boost/predef/library/c/gnu.h new file mode 100644 index 00000000..a2bdfcef --- /dev/null +++ b/cpp/BoostParts/boost/predef/library/c/gnu.h @@ -0,0 +1,62 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_GNU_H +#define BOOST_PREDEF_LIBRARY_C_GNU_H + +#include +#include + +#include + +#if defined(__STDC__) +#include +#elif defined(__cplusplus) +#include +#endif + +/*` +[heading `BOOST_LIB_C_GNU`] + +[@http://en.wikipedia.org/wiki/Glibc GNU glibc] Standard C library. +Version number available as major, and minor. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__GLIBC__`] [__predef_detection__]] + [[`__GNU_LIBRARY__`] [__predef_detection__]] + + [[`__GLIBC__`, `__GLIBC_MINOR__`] [V.R.0]] + [[`__GNU_LIBRARY__`, `__GNU_LIBRARY_MINOR__`] [V.R.0]] + ] + */ + +#define BOOST_LIB_C_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) +# undef BOOST_LIB_C_GNU +# if defined(__GLIBC__) +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GLIBC__,__GLIBC_MINOR__,0) +# else +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GNU_LIBRARY__,__GNU_LIBRARY_MINOR__,0) +# endif +#endif + +#if BOOST_LIB_C_GNU +# define BOOST_LIB_C_GNU_AVAILABLE +#endif + +#define BOOST_LIB_C_GNU_NAME "GNU" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_GNU,BOOST_LIB_C_GNU_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/make.h b/cpp/BoostParts/boost/predef/make.h new file mode 100644 index 00000000..ccee24a1 --- /dev/null +++ b/cpp/BoostParts/boost/predef/make.h @@ -0,0 +1,87 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ +#include + +#ifndef BOOST_PREDEF_MAKE_H +#define BOOST_PREDEF_MAKE_H + +/* +Shorthands for the common version number formats used by vendors... +*/ + +/*` +[heading `BOOST_PREDEF_MAKE_..` macros] + +These set of macros decompose common vendor version number +macros which are composed version, revision, and patch digits. +The naming convention indicates: + +* The base of the specified version number. "`BOOST_PREDEF_MAKE_0X`" for + hexadecimal digits, and "`BOOST_PREDEF_MAKE_10`" for decimal digits. +* The format of the vendor version number. Where "`V`" indicates the version digits, + "`R`" indicates the revision digits, "`P`" indicates the patch digits, and "`0`" + indicates an ignored digit. + +Macros are: +*/ +/*` `BOOST_PREDEF_MAKE_0X_VRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRP(V) BOOST_VERSION_NUMBER((V&0xF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRP(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRPP(V) BOOST_VERSION_NUMBER((V&0xF000)>>12,(V&0xF00)>>8,(V&0xFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRR(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xFF),0) +/*` `BOOST_PREDEF_MAKE_0X_VRRPPPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPPPP(V) BOOST_VERSION_NUMBER((V&0xF000000)>>24,(V&0xFF0000)>>16,(V&0xFFFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRRP(V) BOOST_VERSION_NUMBER((V&0xFF000)>>12,(V&0xFF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRRPP000(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPP000(V) BOOST_VERSION_NUMBER((V&0xF0000000)>>28,(V&0xFF00000)>>20,(V&0xFF000)>>12) +/*` `BOOST_PREDEF_MAKE_10_VPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000) +/*` `BOOST_PREDEF_MAKE_10_VRP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,(V)%10) +/*` `BOOST_PREDEF_MAKE_10_VRP000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,((V)/1000)%10) +/*` `BOOST_PREDEF_MAKE_10_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,((V)/100)%10,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR(V) BOOST_VERSION_NUMBER(((V)/100)%10,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%10,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/1000)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VV00(V)` */ +#define BOOST_PREDEF_MAKE_10_VV00(V) BOOST_VERSION_NUMBER(((V)/100)%100,0,0) +/*` `BOOST_PREDEF_MAKE_10_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR(V) BOOST_VERSION_NUMBER(((V)/100)%100,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VVRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%100,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PP00(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,((V)/100)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PPPP(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,(V)%10000) +/*` `BOOST_PREDEF_MAKE_10_VVRR00PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR00PP00(V) BOOST_VERSION_NUMBER(((V)/100000000)%100,((V)/1000000)%100,((V)/100)%100) +/*` +[heading `BOOST_PREDEF_MAKE_*..` date macros] + +Date decomposition macros return a date in the relative to the 1970 +Epoch date. If the month is not available, January 1st is used as the month and day. +If the day is not available, but the month is, the 1st of the month is used as the day. +*/ +/*` `BOOST_PREDEF_MAKE_DATE(Y,M,D)` */ +#define BOOST_PREDEF_MAKE_DATE(Y,M,D) BOOST_VERSION_NUMBER((Y)%10000-1970,(M)%100,(D)%100) +/*` `BOOST_PREDEF_MAKE_YYYYMMDD(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMMDD(V) BOOST_PREDEF_MAKE_DATE(((V)/10000)%10000,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_YYYY(V)` */ +#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1) +/*` `BOOST_PREDEF_MAKE_YYYYMM(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V),1) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd.h b/cpp/BoostParts/boost/predef/os/bsd.h new file mode 100644 index 00000000..0adc435d --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd.h @@ -0,0 +1,95 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_H +#define BOOST_PREDEF_OS_BSD_H + +/* Special case: OSX will define BSD predefs if the sys/param.h + * header is included. We can guard against that, but only if we + * detect OSX first. Hence we will force include OSX detection + * before doing any BSD detection. + */ +#include + +#include +#include + +/*` +[heading `BOOST_OS_BSD`] + +[@http://en.wikipedia.org/wiki/Berkeley_Software_Distribution BSD] operating system. + +BSD has various branch operating systems possible and each detected +individually. This detects the following variations and sets a specific +version number macro to match: + +* `BOOST_OS_BSD_DRAGONFLY` [@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] +* `BOOST_OS_BSD_FREE` [@http://en.wikipedia.org/wiki/Freebsd FreeBSD] +* `BOOST_OS_BSD_BSDI` [@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] +* `BOOST_OS_BSD_NET` [@http://en.wikipedia.org/wiki/Netbsd NetBSD] +* `BOOST_OS_BSD_OPEN` [@http://en.wikipedia.org/wiki/Openbsd OpenBSD] + +[note The general `BOOST_OS_BSD` is set in all cases to indicate some form +of BSD. If the above variants is detected the corresponding macro is also set.] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`BSD`] [__predef_detection__]] + [[`_SYSTYPE_BSD`] [__predef_detection__]] + + [[`BSD4_2`] [4.2.0]] + [[`BSD4_3`] [4.3.0]] + [[`BSD4_4`] [4.4.0]] + [[`BSD`] [V.R.0]] + ] + */ + +#include +#include +#include +#include +#include + +#ifndef BOOST_OS_BSD +#define BOOST_OS_BSD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(BSD) || \ + defined(_SYSTYPE_BSD) \ + ) +# undef BOOST_OS_BSD +# include +# if !defined(BOOST_OS_BSD) && defined(BSD4_4) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_3) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_2) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD) +# define BOOST_OS_BSD BOOST_PREDEF_MAKE_10_VVRR(BSD) +# endif +# if !defined(BOOST_OS_BSD) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD +# define BOOST_OS_BSD_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NAME "BSD" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd/bsdi.h b/cpp/BoostParts/boost/predef/os/bsd/bsdi.h new file mode 100644 index 00000000..71ea87a2 --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd/bsdi.h @@ -0,0 +1,48 @@ +/* +Copyright Redshift Software, Inc. 2012-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_BSDI_H +#define BOOST_PREDEF_OS_BSD_BSDI_H + +#include + +/*` +[heading `BOOST_OS_BSD_BSDI`] + +[@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__bsdi__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(__bsdi__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd/dragonfly.h b/cpp/BoostParts/boost/predef/os/bsd/dragonfly.h new file mode 100644 index 00000000..9d374398 --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd/dragonfly.h @@ -0,0 +1,50 @@ +/* +Copyright Redshift Software, Inc. 2012-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_DRAGONFLY_H +#define BOOST_PREDEF_OS_BSD_DRAGONFLY_H + +#include + +/*` +[heading `BOOST_OS_BSD_DRAGONFLY`] + +[@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DragonFly__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_DRAGONFLY BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(__DragonFly__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_DRAGONFLY +# if defined(__DragonFly__) +# define BOOST_OS_DRAGONFLY_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_DRAGONFLY +# define BOOST_OS_BSD_DRAGONFLY_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd/free.h b/cpp/BoostParts/boost/predef/os/bsd/free.h new file mode 100644 index 00000000..321d3a3b --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd/free.h @@ -0,0 +1,60 @@ +/* +Copyright Redshift Software, Inc. 2012-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_FREE_H +#define BOOST_PREDEF_OS_BSD_FREE_H + +#include + +/*` +[heading `BOOST_OS_BSD_FREE`] + +[@http://en.wikipedia.org/wiki/Freebsd FreeBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__FreeBSD__`] [__predef_detection__]] + + [[`__FreeBSD_version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(__FreeBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_FREE +# if defined(__FreeBSD_version) +# if __FreeBSD_version < 500000 +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRP000(__FreeBSD_version) +# else +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRR000(__FreeBSD_version) +# endif +# else +# define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_FREE +# define BOOST_OS_BSD_FREE_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_FREE_NAME "Free BSD" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd/net.h b/cpp/BoostParts/boost/predef/os/bsd/net.h new file mode 100644 index 00000000..2a345389 --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd/net.h @@ -0,0 +1,84 @@ +/* +Copyright Redshift Software, Inc. 2012-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_NET_H +#define BOOST_PREDEF_OS_BSD_NET_H + +#include + +/*` +[heading `BOOST_OS_BSD_NET`] + +[@http://en.wikipedia.org/wiki/Netbsd NetBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__NETBSD__`] [__predef_detection__]] + [[`__NetBSD__`] [__predef_detection__]] + + [[`__NETBSD_version`] [V.R.P]] + [[`NetBSD0_8`] [0.8.0]] + [[`NetBSD0_9`] [0.9.0]] + [[`NetBSD1_0`] [1.0.0]] + [[`__NetBSD_Version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(__NETBSD__) || defined(__NetBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_NET +# if defined(__NETBSD__) +# if defined(__NETBSD_version) +# if __NETBSD_version < 500000 +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRP000(__NETBSD_version) +# else +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRR000(__NETBSD_version) +# endif +# else +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# elif defined(__NetBSD__) +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_8) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,8,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_9) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,9,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD1_0) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(__NetBSD_Version) +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VVRR00PP00(__NetBSD_Version) +# endif +# if !defined(BOOST_OS_BSD_NET) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_OS_BSD_NET +# define BOOST_OS_BSD_NET_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NET_NAME "DragonFly BSD" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/bsd/open.h b/cpp/BoostParts/boost/predef/os/bsd/open.h new file mode 100644 index 00000000..2f516441 --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/bsd/open.h @@ -0,0 +1,171 @@ +/* +Copyright Redshift Software, Inc. 2012-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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_OPEN_H +#define BOOST_PREDEF_OS_BSD_OPEN_H + +#include + +/*` +[heading `BOOST_OS_BSD_OPEN`] + +[@http://en.wikipedia.org/wiki/Openbsd OpenBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OpenBSD__`] [__predef_detection__]] + + [[`OpenBSD2_0`] [2.0.0]] + [[`OpenBSD2_1`] [2.1.0]] + [[`OpenBSD2_2`] [2.2.0]] + [[`OpenBSD2_3`] [2.3.0]] + [[`OpenBSD2_4`] [2.4.0]] + [[`OpenBSD2_5`] [2.5.0]] + [[`OpenBSD2_6`] [2.6.0]] + [[`OpenBSD2_7`] [2.7.0]] + [[`OpenBSD2_8`] [2.8.0]] + [[`OpenBSD2_9`] [2.9.0]] + [[`OpenBSD3_0`] [3.0.0]] + [[`OpenBSD3_1`] [3.1.0]] + [[`OpenBSD3_2`] [3.2.0]] + [[`OpenBSD3_3`] [3.3.0]] + [[`OpenBSD3_4`] [3.4.0]] + [[`OpenBSD3_5`] [3.5.0]] + [[`OpenBSD3_6`] [3.6.0]] + [[`OpenBSD3_7`] [3.7.0]] + [[`OpenBSD3_8`] [3.8.0]] + [[`OpenBSD3_9`] [3.9.0]] + [[`OpenBSD4_0`] [4.0.0]] + [[`OpenBSD4_1`] [4.1.0]] + [[`OpenBSD4_2`] [4.2.0]] + [[`OpenBSD4_3`] [4.3.0]] + [[`OpenBSD4_4`] [4.4.0]] + [[`OpenBSD4_5`] [4.5.0]] + [[`OpenBSD4_6`] [4.6.0]] + [[`OpenBSD4_7`] [4.7.0]] + [[`OpenBSD4_8`] [4.8.0]] + [[`OpenBSD4_9`] [4.9.0]] + ] + */ + +#define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(__OpenBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_OPEN +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_OPEN +# define BOOST_OS_BSD_OPEN_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_OPEN_NAME "OpenBSD" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/os/macos.h b/cpp/BoostParts/boost/predef/os/macos.h new file mode 100644 index 00000000..e625a6c7 --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/macos.h @@ -0,0 +1,58 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_OS_MACOS_H +#define BOOST_PREDEF_OS_MACOS_H + +#include +#include + +/*` +[heading `BOOST_OS_MACOS`] + +[@http://en.wikipedia.org/wiki/Mac_OS Mac OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`macintosh`] [__predef_detection__]] + [[`Macintosh`] [__predef_detection__]] + [[`__APPLE__`] [__predef_detection__]] + [[`__MACH__`] [__predef_detection__]] + + [[`__APPLE__`, `__MACH__`] [10.0.0]] + [[ /otherwise/ ] [9.0.0]] + ] + */ + +#define BOOST_OS_MACOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(macintosh) || defined(Macintosh) || \ + (defined(__APPLE__) && defined(__MACH__)) \ + ) +# undef BOOST_OS_MACOS +# if !defined(BOOST_OS_MACOS) && defined(__APPLE__) && defined(__MACH__) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(10,0,0) +# endif +# if !defined(BOOST_OS_MACOS) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(9,0,0) +# endif +#endif + +#if BOOST_OS_MACOS +# define BOOST_OS_MACOS_AVAILABLE +# include +#endif + +#define BOOST_OS_MACOS_NAME "Mac OS" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/os/windows.h b/cpp/BoostParts/boost/predef/os/windows.h new file mode 100644 index 00000000..1316963b --- /dev/null +++ b/cpp/BoostParts/boost/predef/os/windows.h @@ -0,0 +1,51 @@ +/* +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_OS_WINDOWS_H +#define BOOST_PREDEF_OS_WINDOWS_H + +#include +#include + +/*` +[heading `BOOST_OS_WINDOWS`] + +[@http://en.wikipedia.org/wiki/Category:Microsoft_Windows Microsoft Windows] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_WIN32`] [__predef_detection__]] + [[`_WIN64`] [__predef_detection__]] + [[`__WIN32__`] [__predef_detection__]] + [[`__TOS_WIN__`] [__predef_detection__]] + [[`__WINDOWS__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !BOOST_PREDEF_DETAIL_OS_DETECTED && ( \ + defined(_WIN32) || defined(_WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || \ + defined(__WINDOWS__) \ + ) +# undef BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS_AVAILABLE +# include +#endif + +#define BOOST_OS_WINDOWS_NAME "Microsoft Windows" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME) + +#endif diff --git a/cpp/BoostParts/boost/predef/other/endian.h b/cpp/BoostParts/boost/predef/other/endian.h new file mode 100644 index 00000000..9d2a8bcc --- /dev/null +++ b/cpp/BoostParts/boost/predef/other/endian.h @@ -0,0 +1,205 @@ +/* +Copyright Redshift Software, Inc. 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) +*/ + +#ifndef BOOST_PREDEF_ENDIAN_H +#define BOOST_PREDEF_ENDIAN_H + +#include +#include +#include +#include +#include + +/*` +[heading `BOOST_ENDIAN_*`] + +Detection of endian memory ordering. There are four defined macros +in this header that define the various generally possible endian +memory orderings: + +* `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian. +* `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian. +* `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian. +* `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian. + +The detection is conservative in that it only identifies endianness +that it knows for certain. In particular bi-endianness is not +indicated as is it not practically possible to determine the +endianness from anything but an operating system provided +header. And the currently known headers do not define that +programatic bi-endianness is available. + +This implementation is a compilation of various publicly available +information and acquired knowledge: + +# The indispensable documentation of "Pre-defined Compiler Macros" + [@http://sourceforge.net/p/predef/wiki/Endianness Endianness]. +# The various endian specifications available in the + [@http://wikipedia.org/ Wikipedia] computer architecture pages. +# Generally available searches for headers that define endianness. + */ + +#define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER. + * And some OSs provide some for of endian header also. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_LIB_C_GNU +# include +# else +# if BOOST_OS_MACOS +# include +# else +# if BOOST_OS_BSD +# if BOOST_OS_BSD_OPEN +# include +# else +# include +# endif +# endif +# endif +# endif +# if defined(__BYTE_ORDER) +# if (__BYTE_ORDER == __BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if (__BYTE_ORDER == __PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +# if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER) +# if (_BYTE_ORDER == _BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if (_BYTE_ORDER == _LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if (_BYTE_ORDER == _PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +/* Built-in byte-swpped big-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if !BOOST_ENDIAN_BIG_BYTE +# if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(_MIPSEB) || \ + defined(__MIPSEB) || \ + defined(__MIPSEB__) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +/* Built-in byte-swpped little-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if !BOOST_ENDIAN_LITTLE_BYTE +# if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ + defined(_MIPSEL) || \ + defined(__MIPSEL) || \ + defined(__MIPSEL__) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +/* Some architectures are strictly one endianess (as opposed + * the current common bi-endianess). + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# include +# if BOOST_ARCH_M68K || \ + BOOST_ARCH_PARISK || \ + BOOST_ARCH_SYS370 || \ + BOOST_ARCH_SYS390 || \ + BOOST_ARCH_Z +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if BOOST_ARCH_AMD64 || \ + BOOST_ARCH_IA64 || \ + BOOST_ARCH_X86 || \ + BOOST_ARCH_BLACKFIN +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Windows on ARM, if not otherwise detected/specified, is always + * byte-swaped little-endian. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_ARCH_ARM +# include +# if BOOST_OS_WINDOWS +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_BIG_WORD +# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE +#endif + +#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian" +#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian" +#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian" +#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian" + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) + + +#endif diff --git a/cpp/BoostParts/boost/predef/version_number.h b/cpp/BoostParts/boost/predef/version_number.h new file mode 100644 index 00000000..2ecccd2e --- /dev/null +++ b/cpp/BoostParts/boost/predef/version_number.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2005 +Copyright Redshift Software, Inc. 2008-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) +*/ + +#ifndef BOOST_PREDEF_VERSION_NUMBER_H +#define BOOST_PREDEF_VERSION_NUMBER_H + +/*` +[heading `BOOST_VERSION_NUMBER`] + +`` +BOOST_VERSION_NUMBER(major,minor,patch) +`` + +Defines standard version numbers, with these properties: + +* Decimal base whole numbers in the range \[0,1000000000). + The number range is designed to allow for a (2,2,5) triplet. + Which fits within a 32 bit value. +* The `major` number can be in the \[0,99\] range. +* The `minor` number can be in the \[0,99\] range. +* The `patch` number can be in the \[0,99999\] range. +* Values can be specified in any base. As the defined value + is an constant expression. +* Value can be directly used in both preprocessor and compiler + expressions for comparison to other similarly defined values. +* The implementation enforces the individual ranges for the + major, minor, and patch numbers. And values over the ranges + are truncated (modulo). + +*/ +#define BOOST_VERSION_NUMBER(major,minor,patch) \ + ( (((major)%100)*10000000) + (((minor)%100)*100000) + ((patch)%100000) ) + +#define BOOST_VERSION_NUMBER_MAX \ + BOOST_VERSION_NUMBER(99,99,99999) + +#define BOOST_VERSION_NUMBER_ZERO \ + BOOST_VERSION_NUMBER(0,0,0) + +#define BOOST_VERSION_NUMBER_MIN \ + BOOST_VERSION_NUMBER(0,0,1) + +#define BOOST_VERSION_NUMBER_AVAILABLE \ + BOOST_VERSION_NUMBER_MIN + +#define BOOST_VERSION_NUMBER_NOT_AVAILABLE \ + BOOST_VERSION_NUMBER_ZERO + +#endif diff --git a/cpp/BoostParts/boost/preprocessor/tuple/rem.hpp b/cpp/BoostParts/boost/preprocessor/tuple/rem.hpp index 4e3362cb..af668a02 100644 --- a/cpp/BoostParts/boost/preprocessor/tuple/rem.hpp +++ b/cpp/BoostParts/boost/preprocessor/tuple/rem.hpp @@ -38,6 +38,7 @@ # endif # define BOOST_PP_TUPLE_REM_I(size) BOOST_PP_TUPLE_REM_ ## size # endif +# define BOOST_PP_TUPLE_REM_0() # define BOOST_PP_TUPLE_REM_1(e0) e0 # define BOOST_PP_TUPLE_REM_2(e0, e1) e0, e1 # define BOOST_PP_TUPLE_REM_3(e0, e1, e2) e0, e1, e2 diff --git a/cpp/BoostParts/boost/progress.hpp b/cpp/BoostParts/boost/progress.hpp index fbbf04a7..de5fe969 100644 --- a/cpp/BoostParts/boost/progress.hpp +++ b/cpp/BoostParts/boost/progress.hpp @@ -38,7 +38,7 @@ class progress_timer : public timer, private noncopyable public: explicit progress_timer( std::ostream & os = std::cout ) // os is hint; implementation may ignore, particularly in embedded systems - : m_os(os) {} + : timer(), noncopyable(), m_os(os) {} ~progress_timer() { // A) Throwing an exception from a destructor is a Bad Thing. @@ -83,7 +83,7 @@ class progress_display : private noncopyable const std::string & s2 = "", const std::string & s3 = "" ) // os is hint; implementation may ignore, particularly in embedded systems - : m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count); } + : noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count); } void restart( unsigned long expected_count ) // Effects: display appropriate scale diff --git a/cpp/BoostParts/boost/property_map/property_map.hpp b/cpp/BoostParts/boost/property_map/property_map.hpp index 01f96176..b142849f 100644 --- a/cpp/BoostParts/boost/property_map/property_map.hpp +++ b/cpp/BoostParts/boost/property_map/property_map.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -147,6 +148,7 @@ namespace boost { #else template struct property_traits { + // BOOST_STATIC_ASSERT(boost::is_same::value && !"Using pointers as property maps is deprecated"); typedef T value_type; typedef value_type& reference; typedef std::ptrdiff_t key_type; @@ -154,6 +156,7 @@ namespace boost { }; template struct property_traits { + // BOOST_STATIC_ASSERT(boost::is_same::value && !"Using pointers as property maps is deprecated"); typedef T value_type; typedef const value_type& reference; typedef std::ptrdiff_t key_type; diff --git a/cpp/BoostParts/boost/rational.hpp b/cpp/BoostParts/boost/rational.hpp index 468db792..fd04b6bd 100644 --- a/cpp/BoostParts/boost/rational.hpp +++ b/cpp/BoostParts/boost/rational.hpp @@ -28,9 +28,9 @@ // 31 Oct 06 Recoded both operator< to use round-to-negative-infinity // divisions; the rational-value version now uses continued fraction // expansion to avoid overflows, for bug #798357 (Daryle Walker) -// 20 Oct 06 Fix operator bool_type for CW 8.3 (Joaquín M López Muñoz) +// 20 Oct 06 Fix operator bool_type for CW 8.3 (JoaquĂ­n M LĂ³pez Muñoz) // 18 Oct 06 Use EXPLICIT_TEMPLATE_TYPE helper macros from Boost.Config -// (Joaquín M López Muñoz) +// (JoaquĂ­n M LĂ³pez Muñoz) // 27 Dec 05 Add Boolean conversion operator (Daryle Walker) // 28 Sep 02 Use _left versions of operators from operators.hpp // 05 Jul 01 Recode gcd(), avoiding std::swap (Helmut Zeisel) @@ -389,9 +389,11 @@ bool rational::operator< (const rational& r) const // Determine relative order by expanding each value to its simple continued // fraction representation using the Euclidian GCD algorithm. - struct { int_type n, d, q, r; } ts = { this->num, this->den, this->num / - this->den, this->num % this->den }, rs = { r.num, r.den, r.num / r.den, - r.num % r.den }; + struct { int_type n, d, q, r; } + ts = { this->num, this->den, static_cast(this->num / this->den), + static_cast(this->num % this->den) }, + rs = { r.num, r.den, static_cast(r.num / r.den), + static_cast(r.num % r.den) }; unsigned reverse = 0u; // Normalize negative moduli by repeatedly adding the (positive) denominator diff --git a/cpp/BoostParts/boost/regex/v4/perl_matcher_non_recursive.hpp b/cpp/BoostParts/boost/regex/v4/perl_matcher_non_recursive.hpp index f5eb3feb..5c1f7a98 100644 --- a/cpp/BoostParts/boost/regex/v4/perl_matcher_non_recursive.hpp +++ b/cpp/BoostParts/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -703,7 +703,13 @@ bool perl_matcher::match_char_repeat() if(::boost::is_random_access_iterator::value) { BidiIterator end = position; - std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired)); + // Move end forward by "desired", preferably without using distance or advance if we can + // as these can be slow for some iterator types. + std::size_t len = (desired == (std::numeric_limits::max)()) ? 0u : ::boost::re_detail::distance(position, last); + if(desired >= len) + end = last; + else + std::advance(end, desired); BidiIterator origin(position); while((position != end) && (traits_inst.translate(*position, icase) == what)) { @@ -771,7 +777,13 @@ bool perl_matcher::match_set_repeat() if(::boost::is_random_access_iterator::value) { BidiIterator end = position; - std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired)); + // Move end forward by "desired", preferably without using distance or advance if we can + // as these can be slow for some iterator types. + std::size_t len = (desired == (std::numeric_limits::max)()) ? 0u : ::boost::re_detail::distance(position, last); + if(desired >= len) + end = last; + else + std::advance(end, desired); BidiIterator origin(position); while((position != end) && map[static_cast(traits_inst.translate(*position, icase))]) { @@ -840,7 +852,13 @@ bool perl_matcher::match_long_set_repeat() if(::boost::is_random_access_iterator::value) { BidiIterator end = position; - std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired)); + // Move end forward by "desired", preferably without using distance or advance if we can + // as these can be slow for some iterator types. + std::size_t len = (desired == (std::numeric_limits::max)()) ? 0u : ::boost::re_detail::distance(position, last); + if(desired >= len) + end = last; + else + std::advance(end, desired); BidiIterator origin(position); while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase))) { diff --git a/cpp/BoostParts/boost/regex/v4/perl_matcher_recursive.hpp b/cpp/BoostParts/boost/regex/v4/perl_matcher_recursive.hpp index 07a1c20f..8e0e182b 100644 --- a/cpp/BoostParts/boost/regex/v4/perl_matcher_recursive.hpp +++ b/cpp/BoostParts/boost/regex/v4/perl_matcher_recursive.hpp @@ -641,7 +641,13 @@ bool perl_matcher::match_set_repeat() if(::boost::is_random_access_iterator::value) { BidiIterator end = position; - std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired)); + // Move end forward by "desired", preferably without using distance or advance if we can + // as these can be slow for some iterator types. + std::size_t len = (desired == (std::numeric_limits::max)()) ? 0u : ::boost::re_detail::distance(position, last); + if(desired >= len) + end = last; + else + std::advance(end, desired); BidiIterator origin(position); while((position != end) && map[static_cast(traits_inst.translate(*position, icase))]) { @@ -731,7 +737,13 @@ bool perl_matcher::match_long_set_repeat() if(::boost::is_random_access_iterator::value) { BidiIterator end = position; - std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired)); + // Move end forward by "desired", preferably without using distance or advance if we can + // as these can be slow for some iterator types. + std::size_t len = (desired == (std::numeric_limits::max)()) ? 0u : ::boost::re_detail::distance(position, last); + if(desired >= len) + end = last; + else + std::advance(end, desired); BidiIterator origin(position); while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase))) { diff --git a/cpp/BoostParts/boost/smart_ptr/detail/yield_k.hpp b/cpp/BoostParts/boost/smart_ptr/detail/yield_k.hpp index 23eadd80..14af5249 100644 --- a/cpp/BoostParts/boost/smart_ptr/detail/yield_k.hpp +++ b/cpp/BoostParts/boost/smart_ptr/detail/yield_k.hpp @@ -30,7 +30,6 @@ #if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) extern "C" void _mm_pause(); -#pragma intrinsic( _mm_pause ) #define BOOST_SMT_PAUSE _mm_pause(); diff --git a/cpp/BoostParts/boost/thread/barrier.hpp b/cpp/BoostParts/boost/thread/barrier.hpp index ec467ba8..18508221 100644 --- a/cpp/BoostParts/boost/thread/barrier.hpp +++ b/cpp/BoostParts/boost/thread/barrier.hpp @@ -17,51 +17,197 @@ #include #include #include +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL +#include +#else +#include +#endif +#include +#include +#include +#include #include namespace boost { + namespace thread_detail + { +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL + typedef function void_completion_function; + typedef function size_completion_function; +#else + typedef std::function void_completion_function; + typedef std::function size_completion_function; +#endif - class barrier + struct default_barrier_reseter { - public: - BOOST_THREAD_NO_COPYABLE( barrier ) - - barrier(unsigned int count) - : m_threshold(count), m_count(count), m_generation(0) - { - if (count == 0) - boost::throw_exception(thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero.")); - } - - bool wait() - { - boost::unique_lock lock(m_mutex); - unsigned int gen = m_generation; - - if (--m_count == 0) - { - m_generation++; - m_count = m_threshold; - m_cond.notify_all(); - return true; - } - - while (gen == m_generation) - m_cond.wait(lock); - return false; - } - - private: - mutex m_mutex; - condition_variable m_cond; - unsigned int m_threshold; - unsigned int m_count; - unsigned int m_generation; + unsigned int size_; + default_barrier_reseter(unsigned int size) : + size_(size) + { + } + unsigned int operator()() + { + return size_; + } }; -} // namespace boost + struct void_functor_barrier_reseter + { + unsigned int size_; + void_completion_function fct_; + template +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct) + : size_(size), fct_(boost::move(funct)) + {} +#else + void_functor_barrier_reseter(unsigned int size, F funct) + : size_(size), fct_(funct) + {} +#endif + unsigned int operator()() + { + fct_(); + return size_; + } + }; + struct void_fct_ptr_barrier_reseter + { + unsigned int size_; + void(*fct_)(); + void_fct_ptr_barrier_reseter(unsigned int size, void(*funct)()) : + size_(size), fct_(funct) + { + } + unsigned int operator()() + { + fct_(); + return size_; + } + }; + } + class barrier + { + static inline unsigned int check_counter(unsigned int count) + { + if (count == 0) boost::throw_exception( + thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero.")); + return count; + } + struct dummy + { + }; + + public: + BOOST_THREAD_NO_COPYABLE( barrier) + + explicit barrier(unsigned int count) : + m_count(check_counter(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count)) + { + } + + template + barrier( + unsigned int count, +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + BOOST_THREAD_RV_REF(F) funct, +#else + F funct, +#endif + typename enable_if< + typename is_void::type>::type, dummy* + >::type=0 + ) + : m_count(check_counter(count)), + m_generation(0), + fct_(thread_detail::void_functor_barrier_reseter(count, +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + boost::move(funct) +#else + funct +#endif + ) + ) + { + } + + template + barrier( + unsigned int count, +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + BOOST_THREAD_RV_REF(F) funct, +#else + F funct, +#endif + typename enable_if< + typename is_same::type, unsigned int>::type, dummy* + >::type=0 + ) + : m_count(check_counter(count)), + m_generation(0), + fct_( +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + boost::move(funct) +#else + funct +#endif + ) + { + } + + barrier(unsigned int count, void(*funct)()) : + m_count(check_counter(count)), m_generation(0), + fct_(funct + ? thread_detail::size_completion_function(thread_detail::void_fct_ptr_barrier_reseter(count, funct)) + : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count)) + ) + { + } + barrier(unsigned int count, unsigned int(*funct)()) : + m_count(check_counter(count)), m_generation(0), + fct_(funct + ? thread_detail::size_completion_function(funct) + : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count)) + ) + { + } + + bool wait() + { + boost::unique_lock < boost::mutex > lock(m_mutex); + unsigned int gen = m_generation; + + if (--m_count == 0) + { + m_generation++; + m_count = static_cast(fct_()); + BOOST_ASSERT(m_count != 0); + m_cond.notify_all(); + return true; + } + + while (gen == m_generation) + m_cond.wait(lock); + return false; + } + + void count_down_and_wait() + { + wait(); + } + + private: + mutex m_mutex; + condition_variable m_cond; + unsigned int m_count; + unsigned int m_generation; + thread_detail::size_completion_function fct_; + }; + +} // namespace boost #include diff --git a/cpp/BoostParts/boost/thread/detail/config.hpp b/cpp/BoostParts/boost/thread/detail/config.hpp index ce5afc73..4fc29704 100644 --- a/cpp/BoostParts/boost/thread/detail/config.hpp +++ b/cpp/BoostParts/boost/thread/detail/config.hpp @@ -264,6 +264,11 @@ #define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION #endif +#if ! defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP \ + && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_UNWRAP +#define BOOST_THREAD_PROVIDES_FUTURE_UNWRAP +#endif + // FUTURE_INVALID_AFTER_GET #if ! defined BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET \ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET diff --git a/cpp/BoostParts/boost/thread/detail/is_convertible.hpp b/cpp/BoostParts/boost/thread/detail/is_convertible.hpp index 6ed715af..b77620cf 100644 --- a/cpp/BoostParts/boost/thread/detail/is_convertible.hpp +++ b/cpp/BoostParts/boost/thread/detail/is_convertible.hpp @@ -1,8 +1,9 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright 2011-2012 Vicente J. Botet Escriba -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Copyright (C) 2011-2013 Vicente J. Botet Escriba +// +// 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) // // See http://www.boost.org/libs/thread for documentation. // diff --git a/cpp/BoostParts/boost/thread/detail/memory.hpp b/cpp/BoostParts/boost/thread/detail/memory.hpp index 3c1692d0..8c0bf3fe 100644 --- a/cpp/BoostParts/boost/thread/detail/memory.hpp +++ b/cpp/BoostParts/boost/thread/detail/memory.hpp @@ -1,8 +1,9 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright 2011-2012 Vicente J. Botet Escriba -// Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Copyright (C) 2011-2013 Vicente J. Botet Escriba +// +// 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) // // See http://www.boost.org/libs/thread for documentation. // diff --git a/cpp/BoostParts/boost/thread/detail/thread.hpp b/cpp/BoostParts/boost/thread/detail/thread.hpp index e65d76b0..a6e2da30 100644 --- a/cpp/BoostParts/boost/thread/detail/thread.hpp +++ b/cpp/BoostParts/boost/thread/detail/thread.hpp @@ -826,6 +826,19 @@ namespace boost }; void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*); + struct shared_state_base; +#if defined(BOOST_THREAD_PLATFORM_WIN32) + inline void make_ready_at_thread_exit(shared_ptr as) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->make_ready_at_thread_exit(as); + } + } +#else + void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr as); +#endif } namespace this_thread diff --git a/cpp/BoostParts/boost/thread/future.hpp b/cpp/BoostParts/boost/thread/future.hpp index a8717d6a..edcb14e2 100644 --- a/cpp/BoostParts/boost/thread/future.hpp +++ b/cpp/BoostParts/boost/thread/future.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -145,23 +146,23 @@ namespace boost {} }; - class BOOST_SYMBOL_VISIBLE task_moved: - public future_error - { - public: - task_moved(): - future_error(system::make_error_code(future_errc::no_state)) - {} - }; + class BOOST_SYMBOL_VISIBLE task_moved: + public future_error + { + public: + task_moved(): + future_error(system::make_error_code(future_errc::no_state)) + {} + }; - class promise_moved: - public future_error - { - public: - promise_moved(): - future_error(system::make_error_code(future_errc::no_state)) - {} - }; + class promise_moved: + public future_error + { + public: + promise_moved(): + future_error(system::make_error_code(future_errc::no_state)) + {} + }; namespace future_state { @@ -170,13 +171,6 @@ namespace boost namespace detail { -#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - template - struct future_deferred_continuation; - template - struct future_async_continuation; -#endif - struct relocker { boost::unique_lock& lock_; @@ -204,66 +198,51 @@ namespace boost relocker& operator=(relocker const&); }; - struct future_object_base : enable_shared_from_this + struct shared_state_base : enable_shared_from_this { + typedef std::list waiter_list; + // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout. + typedef shared_ptr continuation_ptr_type; boost::exception_ptr exception; bool done; bool is_deferred_; launch policy_; bool is_constructed; - boost::mutex mutex; + mutable boost::mutex mutex; boost::condition_variable waiters; - typedef std::list waiter_list; waiter_list external_waiters; boost::function callback; -//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + // This declaration should be only included conditionally if interruptions are allowed, but is included to maintain the same layout. bool thread_was_interrupted; -//#endif -#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - typedef shared_ptr continuation_ptr_type; -#else - typedef shared_ptr continuation_ptr_type; -#endif + // This declaration should be only included conditionally, but is included to maintain the same layout. continuation_ptr_type continuation_ptr; - -//#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + // This declaration should be only included conditionally, but is included to maintain the same layout. virtual void launch_continuation(boost::unique_lock&) { } -//#endif - future_object_base(): + + shared_state_base(): done(false), is_deferred_(false), policy_(launch::none), - is_constructed(false) - - // This declaration should be only included conditinally, but are included to maintain the same layout. -//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS - , thread_was_interrupted(false) -//#endif - // This declaration should be only included conditinally, but are included to maintain the same layout. -//#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - , continuation_ptr() -//#endif + is_constructed(false), + thread_was_interrupted(false), + continuation_ptr() {} - virtual ~future_object_base() + virtual ~shared_state_base() {} void set_deferred() { is_deferred_ = true; - set_launch_policy(launch::deferred); + policy_ = launch::deferred; } void set_async() { is_deferred_ = false; - set_launch_policy(launch::async); - } - void set_launch_policy(launch policy) - { - policy_ = policy; + policy_ = launch::async; } waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv) @@ -330,23 +309,22 @@ namespace boost } } - - void wait_internal(boost::unique_lock &lock, bool rethrow=true) + void wait_internal(boost::unique_lock &lk, bool rethrow=true) { - do_callback(lock); + do_callback(lk); //if (!done) // fixme why this doesn't work? { if (is_deferred_) { is_deferred_=false; - execute(lock); - //lock.unlock(); + execute(lk); + //lk.unlock(); } else { while(!done) { - waiters.wait(lock); + waiters.wait(lk); } #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS if(rethrow && thread_was_interrupted) @@ -361,7 +339,8 @@ namespace boost } } } - void wait(bool rethrow=true) + + virtual void wait(bool rethrow=true) { boost::unique_lock lock(mutex); wait_internal(lock, rethrow); @@ -412,11 +391,13 @@ namespace boost exception=e; mark_finished_internal(lock); } + void mark_exceptional_finish() { boost::unique_lock lock(mutex); mark_exceptional_finish_internal(boost::current_exception(), lock); } + #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void mark_interrupted_finish() { @@ -424,6 +405,7 @@ namespace boost thread_was_interrupted=true; mark_finished_internal(lock); } + void set_interrupted_at_thread_exit() { unique_lock lk(mutex); @@ -432,9 +414,10 @@ namespace boost { throw_exception(promise_already_satisfied()); } - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + detail::make_ready_at_thread_exit(shared_from_this()); } #endif + void set_exception_at_thread_exit(exception_ptr e) { unique_lock lk(mutex); @@ -444,9 +427,11 @@ namespace boost } exception=e; this->is_constructed = true; - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + detail::make_ready_at_thread_exit(shared_from_this()); + } - bool has_value() + + bool has_value() const { boost::lock_guard lock(mutex); return done && !(exception @@ -455,7 +440,8 @@ namespace boost #endif ); } - bool has_value(unique_lock& ) + + bool has_value(unique_lock& ) const { return done && !(exception #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS @@ -463,7 +449,8 @@ namespace boost #endif ); } - bool has_exception() + + bool has_exception() const { boost::lock_guard lock(mutex); return done && (exception @@ -472,7 +459,8 @@ namespace boost #endif ); } - bool has_exception(unique_lock&) + + bool has_exception(unique_lock&) const { return done && (exception #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS @@ -480,26 +468,58 @@ namespace boost #endif ); } - bool is_deferred() const BOOST_NOEXCEPT { + + bool is_deferred(boost::lock_guard&) const { return is_deferred_; } - launch launch_policy() const BOOST_NOEXCEPT + launch launch_policy(boost::unique_lock&) const { return policy_; } + future_state::state get_state() const + { + boost::lock_guard guard(mutex); + if(!done) + { + return future_state::waiting; + } + else + { + return future_state::ready; + } + } + + exception_ptr get_exception_ptr() + { + boost::unique_lock lock(mutex); + return get_exception_ptr(lock); + } + exception_ptr get_exception_ptr(boost::unique_lock& lock) + { + wait_internal(lock, false); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + if(thread_was_interrupted) + { + return copy_exception(boost::thread_interrupted()); + } +#endif + return exception; + } + template void set_wait_callback(F f,U* u) { boost::lock_guard lock(mutex); callback=boost::bind(f,boost::ref(*u)); } + virtual void execute(boost::unique_lock&) {} private: - future_object_base(future_object_base const&); - future_object_base& operator=(future_object_base const&); + shared_state_base(shared_state_base const&); + shared_state_base& operator=(shared_state_base const&); }; template @@ -590,8 +610,8 @@ namespace boost // Used to create stand-alone futures template - struct future_object: - detail::future_object_base + struct shared_state: + detail::shared_state_base { typedef typename future_traits::storage_type storage_type; typedef typename future_traits::source_reference_type source_reference_type; @@ -601,11 +621,11 @@ namespace boost storage_type result; - future_object(): + shared_state(): result(0) {} - ~future_object() + ~shared_state() {} void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock& lock) @@ -641,34 +661,18 @@ namespace boost #endif } - virtual move_dest_type get() { wait(); return boost::move(*result); } - shared_future_get_result_type get_sh() + virtual shared_future_get_result_type get_sh() { wait(); return *result; } - // todo move this to detail::future_object_base - future_state::state get_state() - { - boost::lock_guard guard(mutex); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - - //void set_value_at_thread_exit(const T & result_) void set_value_at_thread_exit(source_reference_type result_) { @@ -681,7 +685,7 @@ namespace boost result.reset(new T(result_)); this->is_constructed = true; - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + detail::make_ready_at_thread_exit(shared_from_this()); } //void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_) void set_value_at_thread_exit(rvalue_source_type result_) @@ -692,32 +696,31 @@ namespace boost result.reset(new T(boost::move(result_))); //future_traits::init(result,static_cast(result_)); this->is_constructed = true; - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + detail::make_ready_at_thread_exit(shared_from_this()); } private: - future_object(future_object const&); - future_object& operator=(future_object const&); + shared_state(shared_state const&); + shared_state& operator=(shared_state const&); }; template - struct future_object: - detail::future_object_base + struct shared_state: + detail::shared_state_base { typedef typename future_traits::storage_type storage_type; typedef typename future_traits::source_reference_type source_reference_type; - //typedef typename future_traits::rvalue_source_type rvalue_source_type; typedef typename future_traits::move_dest_type move_dest_type; typedef typename future_traits::shared_future_get_result_type shared_future_get_result_type; T* result; - future_object(): + shared_state(): result(0) {} - ~future_object() + ~shared_state() { } @@ -728,53 +731,24 @@ namespace boost mark_finished_internal(lock); } -// void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock& lock) -// { -// future_traits::init(result,static_cast(result_)); -// mark_finished_internal(lock); -// } - void mark_finished_with_result(source_reference_type result_) { boost::unique_lock lock(mutex); mark_finished_with_result_internal(result_, lock); } -// void mark_finished_with_result(rvalue_source_type result_) -// { -// boost::unique_lock lock(mutex); -// mark_finished_with_result_internal(static_cast(result_), lock); -// } - - - T& get() + virtual T& get() { wait(); - //return static_cast(*result); return *result; } - T& get_sh() + virtual T& get_sh() { wait(); - //return static_cast(*result); return *result; } - // todo move this to detail::future_object_base - future_state::state get_state() - { - boost::lock_guard guard(mutex); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } - void set_value_at_thread_exit(T& result_) { unique_lock lk(this->mutex); @@ -783,31 +757,21 @@ namespace boost //future_traits::init(result,result_); result= &result_; this->is_constructed = true; - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + detail::make_ready_at_thread_exit(shared_from_this()); } -// void set_value_at_thread_exit(rvalue_source_type result_) -// { -// unique_lock lk(this->mutex); -// if (this->has_value()) -// throw_exception(promise_already_satisfied()); -// future_traits::init(result,static_cast(result_)); -// this->is_constructed = true; -// get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); -// } - private: - future_object(future_object const&); - future_object& operator=(future_object const&); + shared_state(shared_state const&); + shared_state& operator=(shared_state const&); }; template<> - struct future_object: - detail::future_object_base + struct shared_state: + detail::shared_state_base { typedef void shared_future_get_result_type; - future_object() + shared_state() {} void mark_finished_with_result_internal(boost::unique_lock& lock) @@ -821,27 +785,16 @@ namespace boost mark_finished_with_result_internal(lock); } - void get() + virtual void get() { this->wait(); } - void get_sh() + + virtual void get_sh() { wait(); } - // todo move this to detail::future_object_base - future_state::state get_state() - { - boost::lock_guard guard(mutex); - if(!done) - { - return future_state::waiting; - } - else - { - return future_state::ready; - } - } + void set_value_at_thread_exit() { unique_lock lk(this->mutex); @@ -849,50 +802,65 @@ namespace boost { throw_exception(promise_already_satisfied()); } - this->is_constructed = true; - get_current_thread_data()->make_ready_at_thread_exit(shared_from_this()); + this->is_constructed = true; + detail::make_ready_at_thread_exit(shared_from_this()); } private: - future_object(future_object const&); - future_object& operator=(future_object const&); + shared_state(shared_state const&); + shared_state& operator=(shared_state const&); }; ///////////////////////// - /// future_async_object + /// future_async_shared_state_base ///////////////////////// - template - struct future_async_object: future_object + template + struct future_async_shared_state_base: shared_state { - typedef future_object base_type; - typedef typename base_type::move_dest_type move_dest_type; - + typedef shared_state base_type; + protected: boost::thread thr_; - + void join() + { + if (thr_.joinable()) thr_.join(); + } public: - explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) : - thr_(&future_async_object::run, this, boost::forward(f)) + future_async_shared_state_base() + { + this->set_async(); + } + explicit future_async_shared_state_base(BOOST_THREAD_RV_REF(boost::thread) th) : + thr_(boost::move(th)) { this->set_async(); } - ~future_async_object() + ~future_async_shared_state_base() { - if (thr_.joinable()) thr_.join(); + join(); } - move_dest_type get() + virtual void wait(bool rethrow) { - if (thr_.joinable()) thr_.join(); - // fixme Is the lock needed during the whole scope? - //this->wait(); - boost::unique_lock lock(this->mutex); - this->wait_internal(lock); - - //return static_cast(*(this->result)); - //return boost::move(*(this->result)); - return boost::move(*(this->result)); + join(); + this->base_type::wait(rethrow); } - static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f) + }; + + ///////////////////////// + /// future_async_shared_state + ///////////////////////// + template + struct future_async_shared_state: future_async_shared_state_base + { + typedef future_async_shared_state_base base_type; + + public: + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : + base_type(thread(&future_async_shared_state::run, this, boost::forward(f))) + { + } + + static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) { try { @@ -912,24 +880,17 @@ namespace boost }; template - struct future_async_object: public future_object + struct future_async_shared_state: public future_async_shared_state_base { - typedef future_object base_type; - boost::thread thr_; + typedef future_async_shared_state_base base_type; public: - explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) : - thr_(&future_async_object::run, this, boost::forward(f)) + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : + base_type(thread(&future_async_shared_state::run, this, boost::forward(f))) { - this->set_async(); } - ~future_async_object() - { - if (thr_.joinable()) thr_.join(); - } - - static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f) + static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) { try { @@ -950,37 +911,17 @@ namespace boost }; template - struct future_async_object: future_object + struct future_async_shared_state: future_async_shared_state_base { - typedef future_object base_type; - typedef typename base_type::move_dest_type move_dest_type; - - boost::thread thr_; + typedef future_async_shared_state_base base_type; public: - explicit future_async_object(BOOST_THREAD_FWD_REF(Fp) f) : - thr_(&future_async_object::run, this, boost::forward(f)) + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : + base_type(thread(&future_async_shared_state::run, this, boost::forward(f))) { - this->set_async(); } - ~future_async_object() - { - if (thr_.joinable()) thr_.join(); - } - - move_dest_type get() - { - if (thr_.joinable()) thr_.join(); - // fixme Is the lock needed during the whole scope? - //this->wait(); - boost::unique_lock lock(this->mutex); - this->wait_internal(lock); - - //return static_cast(*(this->result)); - return boost::move(*(this->result)); - } - static void run(future_async_object* that, BOOST_THREAD_FWD_REF(Fp) f) + static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f) { try { @@ -1000,16 +941,16 @@ namespace boost }; ////////////////////////// - /// future_deferred_object + /// future_deferred_shared_state ////////////////////////// template - struct future_deferred_object: future_object + struct future_deferred_shared_state: shared_state { - typedef future_object base_type; + typedef shared_state base_type; Fp func_; public: - explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f) + explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : func_(boost::forward(f)) { this->set_deferred(); @@ -1018,7 +959,11 @@ namespace boost virtual void execute(boost::unique_lock& lck) { try { - this->mark_finished_with_result_internal(func_(), lck); + Fp local_fuct=boost::move(func_); + relocker relock(lck); + Rp res = local_fuct(); + relock.lock(); + this->mark_finished_with_result_internal(boost::move(res), lck); } catch (...) { @@ -1027,13 +972,13 @@ namespace boost } }; template - struct future_deferred_object: future_object + struct future_deferred_shared_state: shared_state { - typedef future_object base_type; + typedef shared_state base_type; Fp func_; public: - explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f) + explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : func_(boost::forward(f)) { this->set_deferred(); @@ -1052,13 +997,13 @@ namespace boost }; template - struct future_deferred_object: future_object + struct future_deferred_shared_state: shared_state { - typedef future_object base_type; + typedef shared_state base_type; Fp func_; public: - explicit future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f) + explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : func_(boost::forward(f)) { this->set_deferred(); @@ -1067,7 +1012,10 @@ namespace boost virtual void execute(boost::unique_lock& lck) { try { - func_(); + Fp local_fuct=boost::move(func_); + relocker relock(lck); + local_fuct(); + relock.lock(); this->mark_finished_with_result_internal(lck); } catch (...) @@ -1078,13 +1026,13 @@ namespace boost }; // template -// struct future_object_alloc: public future_object +// struct shared_state_alloc: public shared_state // { -// typedef future_object base; +// typedef shared_state base; // Allocator alloc_; // // public: -// explicit future_object_alloc(const Allocator& a) +// explicit shared_state_alloc(const Allocator& a) // : alloc_(a) {} // // }; @@ -1095,12 +1043,12 @@ namespace boost struct registered_waiter { - boost::shared_ptr future_; - detail::future_object_base::waiter_list::iterator wait_iterator; + boost::shared_ptr future_; + detail::shared_state_base::waiter_list::iterator wait_iterator; count_type index; - registered_waiter(boost::shared_ptr const& a_future, - detail::future_object_base::waiter_list::iterator wait_iterator_, + registered_waiter(boost::shared_ptr const& a_future, + detail::shared_state_base::waiter_list::iterator wait_iterator_, count_type index_): future_(a_future),wait_iterator(wait_iterator_),index(index_) {} @@ -1124,7 +1072,7 @@ namespace boost #if defined __DECCXX || defined __SUNPRO_CC || defined __hpux locks[i]=boost::unique_lock(futures[i].future_->mutex).move(); #else - locks[i]=boost::unique_lock(futures[i].future_->mutex); // TODO shouldn't be moved explicitly + locks[i]=boost::unique_lock(futures[i].future_->mutex); #endif } } @@ -1200,18 +1148,21 @@ namespace boost struct is_future_type { BOOST_STATIC_CONSTANT(bool, value=false); + typedef void type; }; template struct is_future_type > { BOOST_STATIC_CONSTANT(bool, value=true); + typedef T type; }; template struct is_future_type > { BOOST_STATIC_CONSTANT(bool, value=true); + typedef T type; }; template @@ -1332,8 +1283,9 @@ namespace boost class basic_future : public base_future { protected: + public: - typedef boost::shared_ptr > future_ptr; + typedef boost::shared_ptr > future_ptr; future_ptr future_; @@ -1367,7 +1319,7 @@ namespace boost future_.swap(that.future_); } // functions to check state, and wait for ready - state get_state() const BOOST_NOEXCEPT + state get_state() const { if(!future_) { @@ -1376,27 +1328,34 @@ namespace boost return future_->get_state(); } - bool is_ready() const BOOST_NOEXCEPT + bool is_ready() const { return get_state()==future_state::ready; } - bool has_exception() const BOOST_NOEXCEPT + bool has_exception() const { return future_ && future_->has_exception(); } - bool has_value() const BOOST_NOEXCEPT + bool has_value() const { return future_ && future_->has_value(); } - launch launch_policy() const BOOST_NOEXCEPT + launch launch_policy(boost::unique_lock& lk) const { - if ( future_ ) return future_->launch_policy(); + if ( future_ ) return future_->launch_policy(lk); else return launch(launch::none); } + exception_ptr get_exception_ptr() + { + return future_ + ? future_->get_exception_ptr() + : exception_ptr(); + } + bool valid() const BOOST_NOEXCEPT { return future_ != 0; @@ -1458,23 +1417,33 @@ namespace boost #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005 template BOOST_THREAD_FUTURE - make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f); + make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f); template BOOST_THREAD_FUTURE - make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f); + make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f); #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400) - #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - template - BOOST_THREAD_FUTURE - make_future_async_continuation(boost::unique_lock &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c); + template + struct future_deferred_continuation_shared_state; + template + struct future_async_continuation_shared_state; template BOOST_THREAD_FUTURE - make_future_deferred_continuation(boost::unique_lock &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c); + make_future_async_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); + + template + BOOST_THREAD_FUTURE + make_future_deferred_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); +#endif +#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP + template + struct future_unwrap_shared_state; + template + inline BOOST_THREAD_FUTURE + make_future_unwrap_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f); #endif - } template @@ -1488,9 +1457,24 @@ namespace boost friend class promise; #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION template - friend struct detail::future_async_continuation; + friend struct detail::future_async_continuation_shared_state; template - friend struct detail::future_deferred_continuation; + friend struct detail::future_deferred_continuation_shared_state; + + template + friend BOOST_THREAD_FUTURE + detail::make_future_async_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); + + template + friend BOOST_THREAD_FUTURE + detail::make_future_deferred_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); +#endif +#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP + template + friend struct detail::future_unwrap_shared_state; + template + friend BOOST_THREAD_FUTURE + detail::make_future_unwrap_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f); #endif #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK template friend class packaged_task; // todo check if this works in windows @@ -1501,21 +1485,12 @@ namespace boost template friend BOOST_THREAD_FUTURE - detail::make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f); + detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f); template friend BOOST_THREAD_FUTURE - detail::make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f); + detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f); -#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - template - friend BOOST_THREAD_FUTURE - detail::make_future_async_continuation(boost::unique_lock &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c); - - template - friend BOOST_THREAD_FUTURE - detail::make_future_deferred_continuation(boost::unique_lock &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c); -#endif typedef typename detail::future_traits::move_dest_type move_dest_type; @@ -1527,6 +1502,7 @@ namespace boost public: BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE) typedef future_state::state state; + typedef R value_type; // EXTENSION BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {} @@ -1536,6 +1512,7 @@ namespace boost base_type(boost::move(static_cast(BOOST_THREAD_RV(other)))) { } + inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE >) other); // EXTENSION BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT { @@ -1553,12 +1530,12 @@ namespace boost static_cast(this)->swap(other); } - // todo this functioˆn must be private and friendship provided to the internal users. + // todo this function must be private and friendship provided to the internal users. void set_async() { this->future_->set_async(); } - // todo this functioˆn must be private and friendship provided to the internal users. + // todo this function must be private and friendship provided to the internal users. void set_deferred() { this->future_->set_deferred(); @@ -1571,14 +1548,53 @@ namespace boost { boost::throw_exception(future_uninitialized()); } -#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET future_ptr fut_=this->future_; +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET this->future_.reset(); - return fut_->get(); - -#else - return this->future_->get(); #endif + return fut_->get(); + } + + template + typename boost::disable_if< is_void, move_dest_type>::type + get_or(BOOST_THREAD_RV_REF(R2) v) + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + this->future_->wait(false); + future_ptr fut_=this->future_; +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + this->future_.reset(); +#endif + if (fut_->has_value()) { + return fut_->get(); + } + else { + return boost::move(v); + } + } + + template + typename boost::disable_if< is_void, move_dest_type>::type + get_or(R2 const& v) // EXTENSION + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + this->future_->wait(false); + future_ptr fut_=this->future_; +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + this->future_.reset(); +#endif + if (fut_->has_value()) { + return fut_->get(); + } + else { + return v; + } } @@ -1594,16 +1610,202 @@ namespace boost // inline BOOST_THREAD_FUTURE then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&)); //#endif template - inline BOOST_THREAD_FUTURE::type> - then(BOOST_THREAD_FWD_REF(F) func); + inline BOOST_THREAD_FUTURE::type> + then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION template - inline BOOST_THREAD_FUTURE::type> - then(launch policy, BOOST_THREAD_FWD_REF(F) func); + inline BOOST_THREAD_FUTURE::type> + then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION + + template + inline typename boost::disable_if< is_void, BOOST_THREAD_FUTURE >::type + fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION + template + inline typename boost::disable_if< is_void, BOOST_THREAD_FUTURE >::type + fallback_to(R2 const& v); // EXTENSION + #endif + +//#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP +// inline +// typename boost::enable_if< +// is_future_type, +// value_type +// //BOOST_THREAD_FUTURE::type> +// >::type +// unwrap(); +//#endif + }; BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE BOOST_THREAD_DCL_MOVABLE_END + template + class BOOST_THREAD_FUTURE > : public detail::basic_future > + { + typedef BOOST_THREAD_FUTURE R; + + private: + typedef detail::basic_future base_type; + typedef typename base_type::future_ptr future_ptr; + + friend class shared_future; + friend class promise; + #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + template + friend struct detail::future_async_continuation_shared_state; + template + friend struct detail::future_deferred_continuation_shared_state; + + template + friend BOOST_THREAD_FUTURE + detail::make_future_async_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); + + template + friend BOOST_THREAD_FUTURE + detail::make_future_deferred_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); + #endif +#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP + template + friend struct detail::future_unwrap_shared_state; + template + friend BOOST_THREAD_FUTURE + detail::make_future_unwrap_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f); +#endif + #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK + template friend class packaged_task; // todo check if this works in windows + #else + friend class packaged_task; + #endif + friend class detail::future_waiter; + + template + friend BOOST_THREAD_FUTURE + detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f); + + template + friend BOOST_THREAD_FUTURE + detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f); + + + typedef typename detail::future_traits::move_dest_type move_dest_type; + + BOOST_THREAD_FUTURE(future_ptr a_future): + base_type(a_future) + { + } + + public: + BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE) + typedef future_state::state state; + typedef R value_type; // EXTENSION + + BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {} + + ~BOOST_THREAD_FUTURE() {} + + BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT: + base_type(boost::move(static_cast(BOOST_THREAD_RV(other)))) + { + } + + BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT + { + this->base_type::operator=(boost::move(static_cast(BOOST_THREAD_RV(other)))); + return *this; + } + + shared_future share() + { + return shared_future(::boost::move(*this)); + } + + void swap(BOOST_THREAD_FUTURE& other) + { + static_cast(this)->swap(other); + } + + // todo this function must be private and friendship provided to the internal users. + void set_async() + { + this->future_->set_async(); + } + // todo this function must be private and friendship provided to the internal users. + void set_deferred() + { + this->future_->set_deferred(); + } + + // retrieving the value + move_dest_type get() + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + future_ptr fut_=this->future_; + #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + this->future_.reset(); + #endif + return fut_->get(); + } + move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + this->future_->wait(false); + future_ptr fut_=this->future_; + #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + this->future_.reset(); + #endif + if (fut_->has_value()) return fut_->get(); + else return boost::move(v); + } + + move_dest_type get_or(R const& v) // EXTENSION + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + this->future_->wait(false); + future_ptr fut_=this->future_; + #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + this->future_.reset(); + #endif + if (fut_->has_value()) return fut_->get(); + else return v; + } + + + #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + + // template + // auto then(F&& func) -> BOOST_THREAD_FUTURE; + + //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) + // template + // inline BOOST_THREAD_FUTURE then(RF(*func)(BOOST_THREAD_FUTURE&)); + // template + // inline BOOST_THREAD_FUTURE then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&)); + //#endif + template + inline BOOST_THREAD_FUTURE::type> + then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION + template + inline BOOST_THREAD_FUTURE::type> + then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION + #endif + + #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP + inline + BOOST_THREAD_FUTURE + unwrap(); // EXTENSION + #endif + + }; + template class shared_future : public detail::basic_future { @@ -1614,6 +1816,20 @@ namespace boost friend class detail::future_waiter; friend class promise; +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + template + friend struct detail::future_async_continuation_shared_state; + template + friend struct detail::future_deferred_continuation_shared_state; + + template + friend BOOST_THREAD_FUTURE + detail::make_future_async_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); + + template + friend BOOST_THREAD_FUTURE + detail::make_future_deferred_continuation_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c); +#endif #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK template friend class packaged_task;// todo check if this works in windows #else @@ -1625,6 +1841,7 @@ namespace boost public: BOOST_THREAD_MOVABLE(shared_future) + typedef R value_type; // EXTENSION shared_future(shared_future const& other): base_type(other) @@ -1661,9 +1878,6 @@ namespace boost shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE ) other) BOOST_NOEXCEPT { base_type::operator=(boost::move(static_cast(BOOST_THREAD_RV(other)))); - //shared_future(boost::move(other)).swap(*this); - //this->future_.swap(BOOST_THREAD_RV(other).future_); - //BOOST_THREAD_RV(other).future_.reset(); return *this; } @@ -1673,7 +1887,7 @@ namespace boost } // retrieving the value - typename detail::future_object::shared_future_get_result_type get() + typename detail::shared_state::shared_future_get_result_type get() { if(!this->future_) { @@ -1683,6 +1897,49 @@ namespace boost return this->future_->get_sh(); } + template + typename boost::disable_if< is_void, typename detail::shared_state::shared_future_get_result_type>::type + get_or(BOOST_THREAD_RV_REF(R2) v) // EXTENSION + { + if(!this->future_) + { + boost::throw_exception(future_uninitialized()); + } + future_ptr fut_=this->future_; + fut_->wait(); + if (fut_->has_value()) return fut_->get_sh(); + else return boost::move(v); + } + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +// template +// auto then(F&& func) -> BOOST_THREAD_FUTURE; +// template +// auto then(launch, F&& func) -> BOOST_THREAD_FUTURE; + +//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) +// template +// inline BOOST_THREAD_FUTURE then(RF(*func)(shared_future&)); +// template +// inline BOOST_THREAD_FUTURE then(launch policy, RF(*func)(shared_future&)); +//#endif + template + inline BOOST_THREAD_FUTURE::type> + then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION + template + inline BOOST_THREAD_FUTURE::type> + then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION +#endif +//#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP +// inline +// typename boost::enable_if_c< +// is_future_type::value, +// BOOST_THREAD_FUTURE::type> +// >::type +// unwrap(); +//#endif + }; BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future BOOST_THREAD_DCL_MOVABLE_END @@ -1700,7 +1957,7 @@ namespace boost template class promise { - typedef boost::shared_ptr > future_ptr; + typedef boost::shared_ptr > future_ptr; future_ptr future_; bool future_obtained; @@ -1712,7 +1969,7 @@ namespace boost if(!atomic_load(&future_)) { future_ptr blank; - atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object)); + atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state)); } #include #endif @@ -1724,11 +1981,11 @@ namespace boost template promise(boost::allocator_arg_t, Allocator a) { - typedef typename Allocator::template rebind >::other A2; + typedef typename Allocator::template rebind >::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - future_ = future_ptr(::new(a2.allocate(1)) detail::future_object(), D(a2, 1) ); + future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state(), D(a2, 1) ); future_obtained = false; } #endif @@ -1736,7 +1993,7 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY future_(), #else - future_(new detail::future_object()), + future_(new detail::shared_state()), #endif future_obtained(false) {} @@ -1829,7 +2086,11 @@ namespace boost } future_->mark_exceptional_finish_internal(p, lock); } - + template + void set_exception(E ex) + { + set_exception(copy_exception(ex)); + } // setting the result with deferred notification void set_value_at_thread_exit(const R& r) { @@ -1856,6 +2117,11 @@ namespace boost } future_->set_exception_at_thread_exit(e); } + template + void set_exception_at_thread_exit(E ex) + { + set_exception_at_thread_exit(copy_exception(ex)); + } template void set_wait_callback(F f) @@ -1869,7 +2135,7 @@ namespace boost template class promise { - typedef boost::shared_ptr > future_ptr; + typedef boost::shared_ptr > future_ptr; future_ptr future_; bool future_obtained; @@ -1881,7 +2147,7 @@ namespace boost if(!atomic_load(&future_)) { future_ptr blank; - atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object)); + atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state)); } #include #endif @@ -1893,11 +2159,11 @@ namespace boost template promise(boost::allocator_arg_t, Allocator a) { - typedef typename Allocator::template rebind >::other A2; + typedef typename Allocator::template rebind >::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - future_ = future_ptr(::new(a2.allocate(1)) detail::future_object(), D(a2, 1) ); + future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state(), D(a2, 1) ); future_obtained = false; } #endif @@ -1905,7 +2171,7 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY future_(), #else - future_(new detail::future_object()), + future_(new detail::shared_state()), #endif future_obtained(false) {} @@ -1982,6 +2248,11 @@ namespace boost } future_->mark_exceptional_finish_internal(p, lock); } + template + void set_exception(E ex) + { + set_exception(copy_exception(ex)); + } // setting the result with deferred notification void set_value_at_thread_exit(R& r) @@ -2001,6 +2272,11 @@ namespace boost } future_->set_exception_at_thread_exit(e); } + template + void set_exception_at_thread_exit(E ex) + { + set_exception_at_thread_exit(copy_exception(ex)); + } template void set_wait_callback(F f) @@ -2013,7 +2289,7 @@ namespace boost template <> class promise { - typedef boost::shared_ptr > future_ptr; + typedef boost::shared_ptr > future_ptr; future_ptr future_; bool future_obtained; @@ -2024,7 +2300,7 @@ namespace boost if(!atomic_load(&future_)) { future_ptr blank; - atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object)); + atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state)); } #endif } @@ -2035,11 +2311,11 @@ namespace boost template promise(boost::allocator_arg_t, Allocator a) { - typedef typename Allocator::template rebind >::other A2; + typedef typename Allocator::template rebind >::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - future_ = future_ptr(::new(a2.allocate(1)) detail::future_object(), D(a2, 1) ); + future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state(), D(a2, 1) ); future_obtained = false; } #endif @@ -2047,7 +2323,7 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY future_(), #else - future_(new detail::future_object), + future_(new detail::shared_state), #endif future_obtained(false) {} @@ -2127,6 +2403,11 @@ namespace boost } future_->mark_exceptional_finish_internal(p,lock); } + template + void set_exception(E ex) + { + set_exception(copy_exception(ex)); + } // setting the result with deferred notification void set_value_at_thread_exit() @@ -2146,6 +2427,11 @@ namespace boost } future_->set_exception_at_thread_exit(e); } + template + void set_exception_at_thread_exit(E ex) + { + set_exception_at_thread_exit(copy_exception(ex)); + } template void set_wait_callback(F f) @@ -2172,23 +2458,23 @@ namespace boost { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK template - struct task_base; + struct task_base_shared_state; #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_base: + struct task_base_shared_state: #else template - struct task_base: + struct task_base_shared_state: #endif #else template - struct task_base: + struct task_base_shared_state: #endif - detail::future_object + detail::shared_state { bool started; - task_base(): + task_base_shared_state(): started(false) {} @@ -2256,30 +2542,30 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK template - struct task_object; + struct task_shared_state; #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: F f; - task_object(F const& f_): + task_shared_state(F const& f_): f(f_) {} - task_object(BOOST_THREAD_RV_REF(F) f_): + task_shared_state(BOOST_THREAD_RV_REF(F) f_): f(boost::move(f_)) {} @@ -2346,27 +2632,27 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: F f; - task_object(F const& f_): + task_shared_state(F const& f_): f(f_) {} - task_object(BOOST_THREAD_RV_REF(F) f_): + task_shared_state(BOOST_THREAD_RV_REF(F) f_): f(boost::move(f_)) {} @@ -2431,24 +2717,24 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template - struct task_object : - task_base + struct task_shared_state : + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: R (*f)(); - task_object(R (*f_)()): + task_shared_state(R (*f_)()): f(f_) {} @@ -2513,24 +2799,24 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template - struct task_object : - task_base + struct task_shared_state : + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: R& (*f)(); - task_object(R& (*f_)()): + task_shared_state(R& (*f_)()): f(f_) {} @@ -2594,27 +2880,27 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: F f; - task_object(F const& f_): + task_shared_state(F const& f_): f(f_) {} - task_object(BOOST_THREAD_RV_REF(F) f_): + task_shared_state(BOOST_THREAD_RV_REF(F) f_): f(boost::move(f_)) {} @@ -2676,24 +2962,24 @@ namespace boost #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #else template<> - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif #else template<> - struct task_object: - task_base + struct task_shared_state: + task_base_shared_state #endif { private: - task_object(task_object&); + task_shared_state(task_shared_state&); public: void (*f)(); - task_object(void (*f_)()): + task_shared_state(void (*f_)()): f(f_) {} @@ -2751,30 +3037,28 @@ namespace boost } } }; - } - #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) template class packaged_task { - typedef boost::shared_ptr > task_ptr; - boost::shared_ptr > task; + typedef boost::shared_ptr > task_ptr; + boost::shared_ptr > task; #else template class packaged_task { - typedef boost::shared_ptr > task_ptr; - boost::shared_ptr > task; + typedef boost::shared_ptr > task_ptr; + boost::shared_ptr > task; #endif #else template class packaged_task { - typedef boost::shared_ptr > task_ptr; - boost::shared_ptr > task; + typedef boost::shared_ptr > task_ptr; + boost::shared_ptr > task; #endif bool future_obtained; struct dummy; @@ -2795,16 +3079,16 @@ namespace boost explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args) { typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...); - typedef detail::task_object task_object_type; - task= task_ptr(new task_object_type(f, boost::forward(args)...)); + typedef detail::task_shared_state task_shared_state_type; + task= task_ptr(new task_shared_state_type(f, boost::forward(args)...)); future_obtained=false; } #else explicit packaged_task(R(*f)()) { typedef R(*FR)(); - typedef detail::task_object task_object_type; - task= task_ptr(new task_object_type(f)); + typedef detail::task_shared_state task_shared_state_type; + task= task_ptr(new task_shared_state_type(f)); future_obtained=false; } #endif @@ -2812,8 +3096,8 @@ namespace boost explicit packaged_task(R(*f)()) { typedef R(*FR)(); - typedef detail::task_object task_object_type; - task= task_ptr(new task_object_type(f)); + typedef detail::task_shared_state task_shared_state_type; + task= task_ptr(new task_shared_state_type(f)); future_obtained=false; } #endif @@ -2821,20 +3105,20 @@ namespace boost #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template explicit packaged_task(BOOST_THREAD_FWD_REF(F) f - , typename disable_if::type, packaged_task>, dummy* >::type=0 + , typename boost::disable_if::type, packaged_task>, dummy* >::type=0 ) { typedef typename remove_cv::type>::type FR; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - task = task_ptr(new task_object_type(boost::forward(f))); + task = task_ptr(new task_shared_state_type(boost::forward(f))); future_obtained = false; } @@ -2842,19 +3126,19 @@ namespace boost #else template explicit packaged_task(F const& f - , typename disable_if::type, packaged_task>, dummy* >::type=0 + , typename boost::disable_if::type, packaged_task>, dummy* >::type=0 ) { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - task = task_ptr(new task_object_type(f)); + task = task_ptr(new task_shared_state_type(f)); future_obtained=false; } template @@ -2862,15 +3146,15 @@ namespace boost { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; - task = task_ptr(new task_object_type(boost::forward(f))); + typedef detail::task_shared_state task_shared_state_type; + task = task_ptr(new task_shared_state_type(boost::forward(f))); #else - typedef detail::task_object task_object_type; - task = task_ptr(new task_object_type(boost::move(f))); // TODO forward + typedef detail::task_shared_state task_shared_state_type; + task = task_ptr(new task_shared_state_type(boost::move(f))); // TODO forward #endif #else - typedef detail::task_object task_object_type; - task = task_ptr(new task_object_type(boost::forward(f))); + typedef detail::task_shared_state task_shared_state_type; + task = task_ptr(new task_shared_state_type(boost::forward(f))); #endif future_obtained=false; @@ -2885,18 +3169,18 @@ namespace boost typedef R(*FR)(); #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - typedef typename Allocator::template rebind::other A2; + typedef typename Allocator::template rebind::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - task = task_ptr(::new(a2.allocate(1)) task_object_type(f), D(a2, 1) ); + task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) ); future_obtained = false; } #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR @@ -2908,18 +3192,18 @@ namespace boost typedef typename remove_cv::type>::type FR; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - typedef typename Allocator::template rebind::other A2; + typedef typename Allocator::template rebind::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::forward(f)), D(a2, 1) ); + task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward(f)), D(a2, 1) ); future_obtained = false; } #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES @@ -2928,18 +3212,18 @@ namespace boost { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - typedef typename Allocator::template rebind::other A2; + typedef typename Allocator::template rebind::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; - task = task_ptr(::new(a2.allocate(1)) task_object_type(f), D(a2, 1) ); + task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) ); future_obtained = false; } template @@ -2947,21 +3231,21 @@ namespace boost { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif #else - typedef detail::task_object task_object_type; + typedef detail::task_shared_state task_shared_state_type; #endif - typedef typename Allocator::template rebind::other A2; + typedef typename Allocator::template rebind::other A2; A2 a2(a); typedef thread_detail::allocator_destructor D; #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::forward(f)), D(a2, 1) ); + task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward(f)), D(a2, 1) ); #else - task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::move(f)), D(a2, 1) ); // TODO forward + task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) ); // TODO forward #endif future_obtained = false; } @@ -3018,7 +3302,6 @@ namespace boost // result retrieval BOOST_THREAD_FUTURE get_future() { - if(!task) { boost::throw_exception(task_moved()); @@ -3033,10 +3316,8 @@ namespace boost boost::throw_exception(future_already_retrieved()); } //return BOOST_THREAD_FUTURE(); - } - // execution #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) @@ -3084,7 +3365,6 @@ namespace boost { task->set_wait_callback(f,this); } - }; #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS @@ -3101,26 +3381,26 @@ namespace boost namespace detail { //////////////////////////////// - // make_future_deferred_object + // make_future_deferred_shared_state //////////////////////////////// template BOOST_THREAD_FUTURE - make_future_deferred_object(BOOST_THREAD_FWD_REF(Fp) f) + make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f) { - shared_ptr > - h(new future_deferred_object(boost::forward(f))); + shared_ptr > + h(new future_deferred_shared_state(boost::forward(f))); return BOOST_THREAD_FUTURE(h); } //////////////////////////////// - // make_future_async_object + // make_future_async_shared_state //////////////////////////////// template BOOST_THREAD_FUTURE - make_future_async_object(BOOST_THREAD_FWD_REF(Fp) f) + make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) { - shared_ptr > - h(new future_async_object(boost::forward(f))); + shared_ptr > + h(new future_async_shared_state(boost::forward(f))); return BOOST_THREAD_FUTURE(h); } @@ -3159,7 +3439,7 @@ namespace boost if (int(policy) & int(launch::async)) { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_object( + return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state( BF( thread_detail::decay_copy(boost::forward(f)) , thread_detail::decay_copy(boost::forward(args))... @@ -3177,7 +3457,7 @@ namespace boost else if (int(policy) & int(launch::deferred)) { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_object( + return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state( BF( thread_detail::decay_copy(boost::forward(f)) , thread_detail::decay_copy(boost::forward(args))... @@ -3237,7 +3517,7 @@ namespace boost if (int(policy) & int(launch::async)) { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_object( + return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state( BF( thread_detail::decay_copy(boost::forward(f)) , thread_detail::decay_copy(boost::forward(args))... @@ -3248,18 +3528,14 @@ namespace boost BOOST_THREAD_FUTURE ret = pt.get_future(); ret.set_async(); -//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) -// boost::thread( boost::move(pt), boost::forward(args)... ).detach(); // todo forward -//#else boost::thread( boost::move(pt) ).detach(); -//#endif return ::boost::move(ret); #endif } else if (int(policy) & int(launch::deferred)) { #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) - return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_object( + return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state( BF( thread_detail::decay_copy(boost::forward(f)) , thread_detail::decay_copy(boost::forward(args))... @@ -3269,7 +3545,7 @@ namespace boost std::terminate(); BOOST_THREAD_FUTURE ret; return ::boost::move(ret); -// return boost::detail::make_future_deferred_object( +// return boost::detail::make_future_deferred_shared_state( // BF( // thread_detail::decay_copy(boost::forward(f)) // ) @@ -3332,9 +3608,9 @@ namespace boost template BOOST_THREAD_FUTURE::type> make_future(BOOST_THREAD_FWD_REF(T) value) { - typedef typename decay::type future_type; - promise p; - p.set_value(boost::forward(value)); + typedef typename decay::type future_value_type; + promise p; + p.set_value(boost::forward(value)); return BOOST_THREAD_MAKE_RV_REF(p.get_future()); } @@ -3353,9 +3629,9 @@ namespace boost template BOOST_THREAD_FUTURE::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) { - typedef typename decay::type future_type; - promise p; - p.set_value(boost::forward(value)); + typedef typename decay::type future_value_type; + promise p; + p.set_value(boost::forward(value)); return BOOST_THREAD_MAKE_RV_REF(p.get_future()); } @@ -3368,21 +3644,25 @@ namespace boost } #endif - //////////////////////////////// - // make_exceptional_future - //////////////////////////////// template - BOOST_THREAD_FUTURE make_exceptional_future(exception_ptr ex) + BOOST_THREAD_FUTURE make_ready_future(exception_ptr ex) { promise p; p.set_exception(ex); return BOOST_THREAD_MAKE_RV_REF(p.get_future()); } + template + BOOST_THREAD_FUTURE make_ready_future(E ex) + { + promise p; + p.set_exception(boost::copy_exception(ex)); + return BOOST_THREAD_MAKE_RV_REF(p.get_future()); + } #if 0 template make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE { - typedef decltype(closure() T; + typedef decltype(closure()) T; promise p; try { @@ -3416,105 +3696,74 @@ namespace boost } - //////////////////////////////// - // make_ready_shared_future - //////////////////////////////// - template - shared_future::type> make_ready_shared_future(BOOST_THREAD_FWD_REF(T) value) - { - typedef typename decay::type future_type; - promise p; - p.set_value(boost::forward(value)); - return p.get_future().share(); - } - - - inline shared_future make_ready_shared_future() - { - promise p; - return BOOST_THREAD_MAKE_RV_REF(p.get_future().share()); - - } +// //////////////////////////////// +// // make_ready_shared_future +// //////////////////////////////// +// template +// shared_future::type> make_ready_shared_future(BOOST_THREAD_FWD_REF(T) value) +// { +// typedef typename decay::type future_type; +// promise p; +// p.set_value(boost::forward(value)); +// return p.get_future().share(); +// } +// +// +// inline shared_future make_ready_shared_future() +// { +// promise p; +// return BOOST_THREAD_MAKE_RV_REF(p.get_future().share()); +// +// } +// +// //////////////////////////////// +// // make_exceptional_shared_future +// //////////////////////////////// +// template +// shared_future make_exceptional_shared_future(exception_ptr ex) +// { +// promise p; +// p.set_exception(ex); +// return p.get_future().share(); +// } //////////////////////////////// - // make_exceptional_shared_future - //////////////////////////////// - template - shared_future make_exceptional_shared_future(exception_ptr ex) - { - promise p; - p.set_exception(ex); - return p.get_future().share(); - } - - //////////////////////////////// - // detail::future_async_continuation + // detail::future_async_continuation_shared_state //////////////////////////////// #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION namespace detail { ///////////////////////// - /// future_async_continuation + /// future_async_continuation_shared_state ///////////////////////// template - struct future_async_continuation: future_object + struct future_async_continuation_shared_state: future_async_shared_state_base { - typedef future_object base_type; - typedef typename base_type::move_dest_type move_dest_type; - typedef weak_ptr parent_ptr_type; - F parent; Fp continuation; - boost::thread thr_; public: - future_async_continuation( - F& f, BOOST_THREAD_FWD_REF(Fp) c + future_async_continuation_shared_state( + BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ) : - parent(f.future_), - //continuation(boost::move(c)), - continuation(c), - thr_() + parent(boost::move(f)), + continuation(boost::move(c)) { - this->set_async(); - } - - ~future_async_continuation() - { - if (thr_.get_id()==thread::id()) - { - //BOOST_THREAD_LOG << "ERRORRRRRRRRR ~future_async_continuation " << this << " " << thr_.get_id() << BOOST_THREAD_END_LOG; - return; - } - if (thr_.joinable()) { - thr_.join(); - } } void launch_continuation(boost::unique_lock& lock) { lock.unlock(); - thr_ = thread(&future_async_continuation::run, this); + this->thr_ = thread(&future_async_continuation_shared_state::run, this); } - move_dest_type get() - { - if (thr_.joinable()) thr_.join(); - // fixme Is the lock needed during the whole scope? - //this->wait(); - boost::unique_lock lock(this->mutex); - this->wait_internal(lock); - - // fixme use boost::move - return static_cast(*(this->result)); - } - static void run(future_async_continuation* that) + static void run(future_async_continuation_shared_state* that) { try { - that->mark_finished_with_result(that->continuation(that->parent)); + that->mark_finished_with_result(that->continuation(boost::move(that->parent))); } #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS catch(thread_interrupted& ) @@ -3527,47 +3776,38 @@ namespace boost that->mark_exceptional_finish(); } } + ~future_async_continuation_shared_state() + { + this->join(); + } }; template - struct future_async_continuation: public future_object + struct future_async_continuation_shared_state: public future_async_shared_state_base { - typedef future_object base_type; F parent; Fp continuation; - boost::thread thr_; public: - future_async_continuation( - F& f, BOOST_THREAD_FWD_REF(Fp) c + future_async_continuation_shared_state( + BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ) : - parent(f.future_), - continuation(boost::move(c)), - thr_() + parent(boost::move(f)), + continuation(boost::move(c)) { - this->set_async(); - } - - ~future_async_continuation() - { - if (thr_.get_id()==thread::id()) - { - return; - } - if (thr_.joinable()) thr_.join(); } void launch_continuation(boost::unique_lock& lk) { lk.unlock(); - thr_ = thread(&future_async_continuation::run, this); + this->thr_ = thread(&future_async_continuation_shared_state::run, this); } - static void run(future_async_continuation* that) + static void run(future_async_continuation_shared_state* that) { try { - that->continuation(that->parent); + that->continuation(boost::move(that->parent)); that->mark_finished_with_result(); } #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS @@ -3581,26 +3821,28 @@ namespace boost that->mark_exceptional_finish(); } } + ~future_async_continuation_shared_state() + { + this->join(); + } }; ////////////////////////// - /// future_deferred_continuation + /// future_deferred_continuation_shared_state ////////////////////////// template - struct future_deferred_continuation: future_object + struct future_deferred_continuation_shared_state: shared_state { - typedef future_object base_type; F parent; Fp continuation; public: - future_deferred_continuation( - F& f, BOOST_THREAD_FWD_REF(Fp) c + future_deferred_continuation_shared_state( + BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ) : - parent(f.future_), - //continuation(boost::move(c)) - continuation(c) + parent(boost::move(f)), + continuation(boost::move(c)) { this->set_deferred(); } @@ -3613,7 +3855,12 @@ namespace boost virtual void execute(boost::unique_lock& lck) { try { - this->mark_finished_with_result_internal(continuation(parent), lck); + Fp local_fuct=boost::move(continuation); + F ftmp = boost::move(parent); + relocker relock(lck); + Rp res = local_fuct(boost::move(ftmp)); + relock.lock(); + this->mark_finished_with_result_internal(boost::move(res), lck); } catch (...) { @@ -3623,17 +3870,16 @@ namespace boost }; template - struct future_deferred_continuation: future_object + struct future_deferred_continuation_shared_state: shared_state { - typedef future_object base_type; F parent; Fp continuation; public: - future_deferred_continuation( - F& f, BOOST_THREAD_FWD_REF(Fp) c + future_deferred_continuation_shared_state( + BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ): - parent(f.future_), + parent(boost::move(f)), continuation(boost::move(c)) { this->set_deferred(); @@ -3646,7 +3892,11 @@ namespace boost virtual void execute(boost::unique_lock& lck) { try { - continuation(parent); + Fp local_fuct=boost::move(continuation); + F ftmp = boost::move(parent); + relocker relock(lck); + local_fuct(boost::move(ftmp)); + relock.lock(); this->mark_finished_with_result_internal(lck); } catch (...) @@ -3657,141 +3907,37 @@ namespace boost }; //////////////////////////////// - // make_future_deferred_continuation + // make_future_deferred_continuation_shared_state //////////////////////////////// template BOOST_THREAD_FUTURE - make_future_deferred_continuation( + make_future_deferred_continuation_shared_state( boost::unique_lock &lock, - F& f, BOOST_THREAD_FWD_REF(Fp) c + BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ) { - shared_ptr > - h(new future_deferred_continuation(f, boost::forward(c))); - f.future_->set_continuation_ptr(h, lock); + shared_ptr > + h(new future_deferred_continuation_shared_state(boost::move(f), boost::forward(c))); + h->parent.future_->set_continuation_ptr(h, lock); return BOOST_THREAD_FUTURE(h); } //////////////////////////////// - // make_future_async_continuation + // make_future_async_continuation_shared_state //////////////////////////////// template BOOST_THREAD_FUTURE - make_future_async_continuation( - boost::unique_lock &lock, F& f, BOOST_THREAD_FWD_REF(Fp) c + make_future_async_continuation_shared_state( + boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c ) { - shared_ptr > - h(new future_async_continuation(f, boost::forward(c))); - f.future_->set_continuation_ptr(h, lock); + shared_ptr > + h(new future_async_continuation_shared_state(boost::move(f), boost::forward(c))); + h->parent.future_->set_continuation_ptr(h, lock); return BOOST_THREAD_FUTURE(h); } -// template -// struct future_continuation : future_object -// { -// F& parent; -// C continuation; -// launch policy_; -// -// future_continuation(boost::unique_lock& lk, F& f, BOOST_THREAD_FWD_REF(C) c) : -// parent(f), -// continuation(boost::forward(c)), -// policy_(f.launch_policy()) -// { -// init_continuation(lk); -// } -// future_continuation(boost::unique_lock& lk, F& f, BOOST_THREAD_FWD_REF(C) c, launch policy) : -// parent(f), -// continuation(boost::forward(c)), -// policy_(policy) -// { -// init_continuation(lk); -// } -// ~future_continuation() -// {} -// -// void init_continuation(boost::unique_lock& lk) -// { -// try -// { -// lk.unlock(); -// // fixme what to do depending on inherits_launch_policy_ and policy_? -// if (int(policy_) & int(launch::deferred)) -// { -// R val = continuation(parent); -// next.set_value(boost::move(val)); -// } -// else -// { -// BOOST_THREAD_FUTURE f = async(policy_, continuation, boost::ref(parent)); -// R val = f.get(); -// next.set_value(boost::move(val)); -// } -// } -// catch (...) -// { -// next.set_exception(boost::current_exception()); -// } -// } -// private: -// -// future_continuation(future_continuation const&); -// future_continuation& operator=(future_continuation const&); -// }; -//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) -// template -// struct future_continuation : future_object -// { -// F& parent; -// CR(*continuation)(F&) ; -// launch policy_; -// -// future_continuation(F& f, CR(*c)(F&)) : -// parent(f), -// continuation(c), -// policy_(f.launch_policy()), -// next() -// {} -// future_continuation(F& f, CR(*c)(F&), launch policy) : -// parent(f), -// continuation(c), -// policy_(policy), -// next() -// {} -// ~future_continuation() -// {} -// -// void start_continuation(boost::unique_lock& lk) -// { -// try -// { -// lk.unlock(); -// // fixme what to do depending on inherits_launch_policy_ and policy_? -// if (int(policy_) & int(launch::deferred)) -// { -// R val = continuation(parent); -// next.set_value(boost::move(val)); -// } -// else -// { -// BOOST_THREAD_FUTURE f = async(policy_, continuation, boost::ref(parent)); -// R val = f.get(); -// next.set_value(boost::move(val)); -// } -// } -// catch (...) -// { -// next.set_exception(boost::current_exception()); -// } -// } -// private: -// -// future_continuation(future_continuation const&); -// future_continuation& operator=(future_continuation const&); -// }; -//#endif } //////////////////////////////// @@ -3801,74 +3947,67 @@ namespace boost template template - inline BOOST_THREAD_FUTURE&)>::type> + inline BOOST_THREAD_FUTURE)>::type> BOOST_THREAD_FUTURE::then(launch policy, BOOST_THREAD_FWD_REF(F) func) { - typedef typename boost::result_of&)>::type future_type; + typedef typename boost::result_of)>::type future_type; + BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); - if (this->future_==0) - { - // fixme what to do when the future has no associated state? - return BOOST_THREAD_FUTURE(); - } - - boost::unique_lock lock(this->future_->mutex); - if (int(policy) & int(launch::async)) + boost::unique_lock lock(this->future_->mutex); + if (int(policy) & int(launch::async)) { - return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation, future_type, F>( - lock, *this, boost::forward(func) - ))); + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } + else if (int(policy) & int(launch::deferred)) + { + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } + else + { + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } - else - if (int(policy) & int(launch::deferred)) - { - return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation, future_type, F>( - lock, *this, boost::forward(func) - ))); - } - else - { - // fixme what to do when the policy is invalid? - return BOOST_THREAD_FUTURE(); - } } template template - inline BOOST_THREAD_FUTURE&)>::type> + inline BOOST_THREAD_FUTURE)>::type> BOOST_THREAD_FUTURE::then(BOOST_THREAD_FWD_REF(F) func) { - typedef typename boost::result_of&)>::type future_type; - - if (this->future_==0) - { - //BOOST_THREAD_LOG << "ERROR future::then " << this << BOOST_THREAD_END_LOG; - // fixme what to do when the future has no associated state? - return BOOST_THREAD_FUTURE(); - } + typedef typename boost::result_of)>::type future_type; + BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); boost::unique_lock lock(this->future_->mutex); - if (int(this->launch_policy()) & int(launch::async)) + if (int(this->launch_policy(lock)) & int(launch::async)) { - return boost::detail::make_future_async_continuation, future_type, F>( - lock, *this, boost::forward(func) + return boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) ); } - else if (int(this->launch_policy()) & int(launch::deferred)) + else if (int(this->launch_policy(lock)) & int(launch::deferred)) { this->future_->wait_internal(lock); - return boost::detail::make_future_deferred_continuation, future_type, F>( - lock, *this, boost::forward(func) + return boost::detail::make_future_deferred_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) ); } else { - // fixme what to do when the policy is invalid? - return BOOST_THREAD_FUTURE(); + return boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ); } } + + //#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) // template // template @@ -3922,8 +4061,180 @@ namespace boost // } //#endif + template + template + inline BOOST_THREAD_FUTURE)>::type> + shared_future::then(launch policy, BOOST_THREAD_FWD_REF(F) func) + { + + typedef typename boost::result_of)>::type future_type; + BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); + + boost::unique_lock lock(this->future_->mutex); + if (int(policy) & int(launch::async)) + { + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } + else if (int(policy) & int(launch::deferred)) + { + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } + else + { + return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ))); + } + + } + template + template + inline BOOST_THREAD_FUTURE)>::type> + shared_future::then(BOOST_THREAD_FWD_REF(F) func) + { + + typedef typename boost::result_of)>::type future_type; + + BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); + + boost::unique_lock lock(this->future_->mutex); + if (int(this->launch_policy(lock)) & int(launch::async)) + { + return boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ); + } + else if (int(this->launch_policy(lock)) & int(launch::deferred)) + { + this->future_->wait_internal(lock); + return boost::detail::make_future_deferred_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ); + } + else + { + return boost::detail::make_future_async_continuation_shared_state, future_type, F>( + lock, boost::move(*this), boost::forward(func) + ); + } + } + namespace detail + { + template + struct mfallbacker_to + { + T value_; + typedef T result_type; + mfallbacker_to(BOOST_THREAD_RV_REF(T) v) + : value_(boost::move(v)) + {} + + T operator()(BOOST_THREAD_FUTURE fut) + { + return fut.get_or(boost::move(value_)); + + } + }; + template + struct cfallbacker_to + { + T value_; + typedef T result_type; + cfallbacker_to(T const& v) + : value_(v) + {} + + T operator()(BOOST_THREAD_FUTURE fut) + { + return fut.get_or(value_); + + } + }; + } + //////////////////////////////// + // future future::fallback_to(R&& v); + //////////////////////////////// + + template + template + inline typename boost::disable_if< is_void, BOOST_THREAD_FUTURE >::type + BOOST_THREAD_FUTURE::fallback_to(BOOST_THREAD_RV_REF(R2) v) + { + return then(detail::mfallbacker_to(boost::move(v))); + } + + template + template + inline typename boost::disable_if< is_void, BOOST_THREAD_FUTURE >::type + BOOST_THREAD_FUTURE::fallback_to(R2 const& v) + { + return then(detail::cfallbacker_to(v)); + } + #endif +#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP + namespace detail + { + + ///////////////////////// + /// future_unwrap_shared_state + ///////////////////////// + + template + struct future_unwrap_shared_state: shared_state + { + F parent; + public: + explicit future_unwrap_shared_state( + BOOST_THREAD_RV_REF(F) f + ) : + parent(boost::move(f)) + { + } + virtual void wait(bool ) // todo see if rethrow must be used + { + boost::unique_lock lock(mutex); + parent.get().wait(); + } + virtual Rp get() + { + boost::unique_lock lock(mutex); + return parent.get().get(); + } + + }; + + template + BOOST_THREAD_FUTURE + make_future_unwrap_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f) + { + shared_ptr > + h(new future_unwrap_shared_state(boost::move(f))); + h->parent.future_->set_continuation_ptr(h, lock); + return BOOST_THREAD_FUTURE(h); + } + } + + template + inline BOOST_THREAD_FUTURE::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE >) other): + base_type(other.unwrap()) + { + } + + template + BOOST_THREAD_FUTURE + BOOST_THREAD_FUTURE >::unwrap() + { + BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized()); + boost::unique_lock lock(this->future_->mutex); + return boost::detail::make_future_unwrap_shared_state >, R2>(lock, boost::move(*this)); + } +#endif } #endif // BOOST_NO_EXCEPTION diff --git a/cpp/BoostParts/boost/thread/lock_types.hpp b/cpp/BoostParts/boost/thread/lock_types.hpp index 2d40d227..dcbdc90e 100644 --- a/cpp/BoostParts/boost/thread/lock_types.hpp +++ b/cpp/BoostParts/boost/thread/lock_types.hpp @@ -1112,6 +1112,10 @@ namespace boost { return exclusive.owns_lock(); } + Mutex* mutex() const BOOST_NOEXCEPT + { + return exclusive.mutex(); + } }; BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock BOOST_THREAD_DCL_MOVABLE_END @@ -1187,7 +1191,7 @@ private unique_lock { return base::owns_lock(); } - Mutex* mutex() const + Mutex* mutex() const BOOST_NOEXCEPT { return base::mutex(); } diff --git a/cpp/BoostParts/boost/thread/pthread/condition_variable.hpp b/cpp/BoostParts/boost/thread/pthread/condition_variable.hpp index abebeb7f..b1b76b01 100644 --- a/cpp/BoostParts/boost/thread/pthread/condition_variable.hpp +++ b/cpp/BoostParts/boost/thread/pthread/condition_variable.hpp @@ -200,15 +200,15 @@ namespace boost #if defined BOOST_THREAD_USES_DATETIME template - bool timed_wait(lock_type& m,boost::system_time const& wait_until) + bool timed_wait(lock_type& m,boost::system_time const& abs_time) { - struct timespec const timeout=detail::to_timespec(wait_until); + struct timespec const timeout=detail::to_timespec(abs_time); return do_wait_until(m, timeout); } template - bool timed_wait(lock_type& m,xtime const& wait_until) + bool timed_wait(lock_type& m,xtime const& abs_time) { - return timed_wait(m,system_time(wait_until)); + return timed_wait(m,system_time(abs_time)); } template @@ -218,20 +218,20 @@ namespace boost } template - bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred) { while (!pred()) { - if(!timed_wait(m, wait_until)) + if(!timed_wait(m, abs_time)) return pred(); } return true; } template - bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred) { - return timed_wait(m,system_time(wait_until),pred); + return timed_wait(m,system_time(abs_time),pred); } template diff --git a/cpp/BoostParts/boost/thread/pthread/condition_variable_fwd.hpp b/cpp/BoostParts/boost/thread/pthread/condition_variable_fwd.hpp index e567fc87..e18030fd 100644 --- a/cpp/BoostParts/boost/thread/pthread/condition_variable_fwd.hpp +++ b/cpp/BoostParts/boost/thread/pthread/condition_variable_fwd.hpp @@ -98,21 +98,21 @@ namespace boost #if defined BOOST_THREAD_USES_DATETIME inline bool timed_wait( unique_lock& m, - boost::system_time const& wait_until) + boost::system_time const& abs_time) { #if defined BOOST_THREAD_WAIT_BUG - struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG); + struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG); return do_wait_until(m, timeout); #else - struct timespec const timeout=detail::to_timespec(wait_until); + struct timespec const timeout=detail::to_timespec(abs_time); return do_wait_until(m, timeout); #endif } bool timed_wait( unique_lock& m, - xtime const& wait_until) + xtime const& abs_time) { - return timed_wait(m,system_time(wait_until)); + return timed_wait(m,system_time(abs_time)); } template @@ -126,11 +126,11 @@ namespace boost template bool timed_wait( unique_lock& m, - boost::system_time const& wait_until,predicate_type pred) + boost::system_time const& abs_time,predicate_type pred) { while (!pred()) { - if(!timed_wait(m, wait_until)) + if(!timed_wait(m, abs_time)) return pred(); } return true; @@ -139,9 +139,9 @@ namespace boost template bool timed_wait( unique_lock& m, - xtime const& wait_until,predicate_type pred) + xtime const& abs_time,predicate_type pred) { - return timed_wait(m,system_time(wait_until),pred); + return timed_wait(m,system_time(abs_time),pred); } template diff --git a/cpp/BoostParts/boost/thread/pthread/thread_data.hpp b/cpp/BoostParts/boost/thread/pthread/thread_data.hpp index 6fd19f26..039f8ee3 100644 --- a/cpp/BoostParts/boost/thread/pthread/thread_data.hpp +++ b/cpp/BoostParts/boost/thread/pthread/thread_data.hpp @@ -82,7 +82,7 @@ namespace boost namespace detail { - struct future_object_base; + struct shared_state_base; struct tss_cleanup_function; struct thread_exit_callback_node; struct tss_data_node @@ -121,7 +121,7 @@ namespace boost > notify_list_t; notify_list_t notify; - typedef std::vector > async_states_t; + typedef std::vector > async_states_t; async_states_t async_states_; //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS @@ -154,7 +154,7 @@ namespace boost notify.push_back(std::pair(cv, m)); } - void make_ready_at_thread_exit(shared_ptr as) + void make_ready_at_thread_exit(shared_ptr as) { async_states_.push_back(as); } diff --git a/cpp/BoostParts/boost/thread/win32/condition_variable.hpp b/cpp/BoostParts/boost/thread/win32/condition_variable.hpp index 64a81606..359c21ec 100644 --- a/cpp/BoostParts/boost/thread/win32/condition_variable.hpp +++ b/cpp/BoostParts/boost/thread/win32/condition_variable.hpp @@ -191,18 +191,17 @@ namespace boost struct entry_manager { entry_ptr const entry; + boost::mutex& internal_mutex; BOOST_THREAD_NO_COPYABLE(entry_manager) - entry_manager(entry_ptr const& entry_): - entry(entry_) + entry_manager(entry_ptr const& entry_, boost::mutex& mutex_): + entry(entry_), internal_mutex(mutex_) {} ~entry_manager() { - //if(! entry->is_notified()) // several regression #7657 - { + boost::lock_guard internal_lock(internal_mutex); entry->remove_waiter(); - } } list_entry* operator->() @@ -218,7 +217,7 @@ namespace boost { relocker locker(lock); - entry_manager entry(get_wait_entry()); + entry_manager entry(get_wait_entry(), internal_mutex); locker.unlock(); @@ -366,7 +365,11 @@ namespace boost const chrono::time_point& t) { using namespace chrono; - do_wait(lock, ceil(t-Clock::now()).count()); + chrono::time_point now = Clock::now(); + if (t<=now) { + return cv_status::timeout; + } + do_wait(lock, ceil(t-now).count()); return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; } @@ -378,6 +381,10 @@ namespace boost const chrono::duration& d) { using namespace chrono; + if (d<=chrono::duration::zero()) { + return cv_status::timeout; + } + steady_clock::time_point c_now = steady_clock::now(); do_wait(lock, ceil(d).count()); return steady_clock::now() - c_now < d ? cv_status::no_timeout : @@ -479,7 +486,11 @@ namespace boost const chrono::time_point& t) { using namespace chrono; - do_wait(lock, ceil(t-Clock::now()).count()); + chrono::time_point now = Clock::now(); + if (t<=now) { + return cv_status::timeout; + } + do_wait(lock, ceil(t-now).count()); return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; } @@ -491,6 +502,9 @@ namespace boost const chrono::duration& d) { using namespace chrono; + if (d<=chrono::duration::zero()) { + return cv_status::timeout; + } steady_clock::time_point c_now = steady_clock::now(); do_wait(lock, ceil(d).count()); return steady_clock::now() - c_now < d ? cv_status::no_timeout : diff --git a/cpp/BoostParts/boost/thread/win32/once.hpp b/cpp/BoostParts/boost/thread/win32/once.hpp index 689b2c11..fd7ccacd 100644 --- a/cpp/BoostParts/boost/thread/win32/once.hpp +++ b/cpp/BoostParts/boost/thread/win32/once.hpp @@ -363,7 +363,7 @@ namespace boost } } #else -#ifndef BOOST_MSVC +#if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL) template void call_once(once_flag& flag,Function f) { diff --git a/cpp/BoostParts/boost/thread/win32/thread_data.hpp b/cpp/BoostParts/boost/thread/win32/thread_data.hpp index 09faff9d..d2db5154 100644 --- a/cpp/BoostParts/boost/thread/win32/thread_data.hpp +++ b/cpp/BoostParts/boost/thread/win32/thread_data.hpp @@ -72,7 +72,7 @@ namespace boost namespace detail { - struct future_object_base; + struct shared_state_base; struct tss_cleanup_function; struct thread_exit_callback_node; struct tss_data_node @@ -102,7 +102,7 @@ namespace boost > notify_list_t; notify_list_t notify; - typedef std::vector > async_states_t; + typedef std::vector > async_states_t; async_states_t async_states_; //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS // These data must be at the end so that the access to the other fields doesn't change @@ -148,12 +148,12 @@ namespace boost virtual void run()=0; - void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m) { notify.push_back(std::pair(cv, m)); } - void make_ready_at_thread_exit(shared_ptr as) + void make_ready_at_thread_exit(shared_ptr as) { async_states_.push_back(as); } diff --git a/cpp/BoostParts/boost/thread/win32/thread_primitives.hpp b/cpp/BoostParts/boost/thread/win32/thread_primitives.hpp index 451d9c70..499daed9 100644 --- a/cpp/BoostParts/boost/thread/win32/thread_primitives.hpp +++ b/cpp/BoostParts/boost/thread/win32/thread_primitives.hpp @@ -15,10 +15,11 @@ #include #include #include +//#include #include #ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -#if _WIN32_WINNT >= 0x0600 +#if _WIN32_WINNT >= 0x0600 && ! defined _WIN32_WINNT_WS08 #define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 #endif #endif diff --git a/cpp/BoostParts/boost/throw_exception.hpp b/cpp/BoostParts/boost/throw_exception.hpp index c1bff437..200683ec 100644 --- a/cpp/BoostParts/boost/throw_exception.hpp +++ b/cpp/BoostParts/boost/throw_exception.hpp @@ -1,6 +1,6 @@ #ifndef UUID_AA15E74A856F11E08B8D93F24824019B #define UUID_AA15E74A856F11E08B8D93F24824019B -#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) @@ -41,8 +41,11 @@ #if !defined( BOOST_EXCEPTION_DISABLE ) # include +#if !defined(BOOST_THROW_EXCEPTION_CURRENT_FUNCTION) # include -# define BOOST_THROW_EXCEPTION(x) ::boost::exception_detail::throw_exception_(x,BOOST_CURRENT_FUNCTION,__FILE__,__LINE__) +# define BOOST_THROW_EXCEPTION_CURRENT_FUNCTION BOOST_CURRENT_FUNCTION +#endif +# define BOOST_THROW_EXCEPTION(x) ::boost::exception_detail::throw_exception_(x,BOOST_THROW_EXCEPTION_CURRENT_FUNCTION,__FILE__,__LINE__) #else # define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x) #endif diff --git a/cpp/BoostParts/boost/type_traits.hpp b/cpp/BoostParts/boost/type_traits.hpp index ff75050d..9267a717 100644 --- a/cpp/BoostParts/boost/type_traits.hpp +++ b/cpp/BoostParts/boost/type_traits.hpp @@ -50,6 +50,7 @@ #include "boost/type_traits/is_compound.hpp" #include "boost/type_traits/is_const.hpp" #include "boost/type_traits/is_convertible.hpp" +#include "boost/type_traits/is_copy_constructible.hpp" #include "boost/type_traits/is_empty.hpp" #include "boost/type_traits/is_enum.hpp" #include "boost/type_traits/is_float.hpp" diff --git a/cpp/BoostParts/boost/type_traits/is_copy_constructible.hpp b/cpp/BoostParts/boost/type_traits/is_copy_constructible.hpp new file mode 100644 index 00000000..e90ecb76 --- /dev/null +++ b/cpp/BoostParts/boost/type_traits/is_copy_constructible.hpp @@ -0,0 +1,122 @@ +// (C) Copyright Antony Polukhin 2013. +// +// Use, modification and distribution are subject to 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). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED +#define BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +// should be the last #include +#include + +namespace boost { + +namespace detail{ + +template +struct is_copy_constructible_impl2 { + +// Intel compiler has problems with SFINAE for copy constructors and deleted functions: +// +// error: function *function_name* cannot be referenced -- it is a deleted function +// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval()))* = 0); +// ^ +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) + +#ifdef BOOST_NO_CXX11_DECLTYPE + template + static boost::type_traits::yes_type test(T1&, boost::mpl::int_()))>* = 0); +#else + template + static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval()))* = 0); +#endif + + static boost::type_traits::no_type test(...); +#else + template + static boost::type_traits::no_type test(T1&, typename T1::boost_move_no_copy_constructor_or_assign* = 0); + static boost::type_traits::yes_type test(...); +#endif + + // If you see errors like this: + // + // `'T::T(const T&)' is private` + // `boost/type_traits/is_copy_constructible.hpp:68:5: error: within this context` + // + // then you are trying to call that macro for a structure defined like that: + // + // struct T { + // ... + // private: + // T(const T &); + // ... + // }; + // + // To fix that you must modify your structure: + // + // // C++03 and C++11 version + // struct T: private boost::noncopyable { + // ... + // private: + // T(const T &); + // ... + // }; + // + // // C++11 version + // struct T { + // ... + // private: + // T(const T &) = delete; + // ... + // }; + BOOST_STATIC_CONSTANT(bool, value = ( + sizeof(test( + boost::declval::type>() + )) == sizeof(boost::type_traits::yes_type) + || + boost::is_rvalue_reference::value + )); +}; + +template +struct is_copy_constructible_impl2 { + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_copy_constructible_impl { + + BOOST_STATIC_CONSTANT(bool, value = ( + boost::detail::is_copy_constructible_impl2< + boost::is_base_and_derived::value, + T + >::value + )); +}; + +} // namespace detail + +BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_copy_constructible,T,::boost::detail::is_copy_constructible_impl::value) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_constructible,void,false) +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_constructible,void const,false) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_constructible,void const volatile,false) +BOOST_TT_AUX_BOOL_TRAIT_SPEC1(is_copy_constructible,void volatile,false) +#endif + +} // namespace boost + +#include + +#endif // BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED diff --git a/cpp/BoostParts/boost/type_traits/is_integral.hpp b/cpp/BoostParts/boost/type_traits/is_integral.hpp index 4ca97340..1ab27fd3 100644 --- a/cpp/BoostParts/boost/type_traits/is_integral.hpp +++ b/cpp/BoostParts/boost/type_traits/is_integral.hpp @@ -73,6 +73,12 @@ BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,__int64,true) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,boost::int128_type,true) BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,boost::uint128_type,true) #endif +#ifndef BOOST_NO_CXX11_CHAR16_T +BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,char16_t,true) +#endif +#ifndef BOOST_NO_CXX11_CHAR32_T +BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,char32_t,true) +#endif #endif // non-CodeGear implementation diff --git a/cpp/BoostParts/boost/units/detail/utility.hpp b/cpp/BoostParts/boost/units/detail/utility.hpp deleted file mode 100644 index da46b456..00000000 --- a/cpp/BoostParts/boost/units/detail/utility.hpp +++ /dev/null @@ -1,104 +0,0 @@ -// Boost.Units - A C++ library for zero-overhead dimensional analysis and -// unit/quantity manipulation and conversion -// -// Copyright (C) 2003-2008 Matthias Christian Schabel -// Copyright (C) 2008 Steven Watanabe -// -// 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_UNITS_UTILITY_HPP -#define BOOST_UNITS_UTILITY_HPP - -#include -#include -#include - -#if defined(__GLIBCXX__) || defined(__GLIBCPP__) -#define BOOST_UNITS_USE_DEMANGLING -#include -#endif // __GNUC__ - -#ifdef BOOST_UNITS_USE_DEMANGLING - -#include - -namespace boost { - -namespace units { - -namespace detail { - -inline -std::string -demangle(const char* name) -{ - // need to demangle C++ symbols - char* realname; - std::size_t len; - int stat; - - realname = abi::__cxa_demangle(name,NULL,&len,&stat); - - if (realname != NULL) - { - std::string out(realname); - - std::free(realname); - - boost::replace_all(out,"boost::units::",""); - - return out; - } - - return std::string("demangle :: error - unable to demangle specified symbol"); -} - -} // namespace detail - -template -std::string simplify_typename(const L& /*source*/) -{ - const std::string demangled = detail::demangle(typeid(L).name()); - - return demangled; -} - -} // namespace units - -} // namespace boost - -#else // BOOST_UNITS_USE_DEMANGLING - -namespace boost { - -namespace units { - -namespace detail { - -inline -std::string -demangle(const char* name) -{ - return name; -} - -} // namespace detail - -template -std::string simplify_typename(const L& /*source*/) -{ - return std::string(typeid(L).name()); -} - -} // namespace units - -} // namespace boost - -// To get system-specific predefined macros: -// gcc -arch ppc -dM -E - < /dev/null | sort - -#endif // BOOST_UNITS_USE_DEMANGLING - -#endif // BOOST_UNITS_UTILITY_HPP diff --git a/cpp/BoostParts/boost/unordered/detail/allocate.hpp b/cpp/BoostParts/boost/unordered/detail/allocate.hpp index e07c7082..6671607e 100644 --- a/cpp/BoostParts/boost/unordered/detail/allocate.hpp +++ b/cpp/BoostParts/boost/unordered/detail/allocate.hpp @@ -234,9 +234,11 @@ namespace boost { namespace unordered { namespace detail { #pragma warning(disable:4100) // unreferenced formal parameter #endif - template - inline void destroy(T* x) { - x->~T(); + namespace func { + template + inline void destroy(T* x) { + x->~T(); + } } #if defined(BOOST_MSVC) @@ -257,13 +259,12 @@ namespace boost { namespace unordered { namespace detail { template struct expr_test; template struct expr_test : T {}; - template static char for_expr_test(U const&); # define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \ template \ static typename boost::unordered::detail::expr_test< \ BOOST_PP_CAT(choice, result), \ - sizeof(boost::unordered::detail::for_expr_test(( \ + sizeof(for_expr_test(( \ (expression), \ 0)))>::type test( \ BOOST_PP_CAT(choice, count)) @@ -276,6 +277,7 @@ namespace boost { namespace unordered { namespace detail { # define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \ struct BOOST_PP_CAT(has_, name) \ { \ + template static char for_expr_test(U const&); \ BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \ boost::unordered::detail::make< thing >().name args); \ BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \ @@ -473,6 +475,9 @@ namespace boost { namespace unordered { namespace detail { # endif + namespace func + { + template inline Alloc call_select_on_container_copy_construction(const Alloc& rhs, typename boost::enable_if_c< @@ -510,6 +515,8 @@ namespace boost { namespace unordered { namespace detail { return (std::numeric_limits::max)(); } + } // namespace func. + template struct allocator_traits { @@ -589,7 +596,7 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::has_destroy::value>::type destroy(Alloc&, T* p) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # elif !defined(BOOST_NO_SFINAE_EXPR) @@ -623,7 +630,7 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::has_destroy::value>::type destroy(Alloc&, T* p) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # else @@ -669,21 +676,22 @@ namespace boost { namespace unordered { namespace detail { boost::is_same::value, void*>::type = 0) { - boost::unordered::detail::destroy(p); + boost::unordered::detail::func::destroy(p); } # endif static size_type max_size(const Alloc& a) { - return boost::unordered::detail::call_max_size(a); + return boost::unordered::detail::func:: + call_max_size(a); } // Allocator propagation on construction static Alloc select_on_container_copy_construction(Alloc const& rhs) { - return boost::unordered::detail:: + return boost::unordered::detail::func:: call_select_on_container_copy_construction(rhs); } @@ -758,7 +766,7 @@ namespace boost { namespace unordered { namespace detail { #endif -namespace boost { namespace unordered { namespace detail { +namespace boost { namespace unordered { namespace detail { namespace func { //////////////////////////////////////////////////////////////////////////// // call_construct @@ -792,7 +800,7 @@ namespace boost { namespace unordered { namespace detail { template inline void destroy_value_impl(Alloc&, T* x) { - boost::unordered::detail::destroy(x); + boost::unordered::detail::func::destroy(x); } @@ -802,7 +810,7 @@ namespace boost { namespace unordered { namespace detail { template inline void destroy_value_impl(Alloc&, T* x) { - boost::unordered::detail::destroy(x); + boost::unordered::detail::func::destroy(x); } #endif @@ -818,7 +826,7 @@ namespace boost { namespace unordered { namespace detail { template \ void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \ { \ - boost::unordered::detail::call_construct(alloc, ptr); \ + boost::unordered::detail::func::call_construct(alloc, ptr); \ } \ \ BOOST_PP_REPEAT_FROM_TO(1, n, \ @@ -830,7 +838,7 @@ namespace boost { namespace unordered { namespace detail { void construct_from_tuple(Alloc& alloc, T* ptr, \ namespace_ tuple const& x) \ { \ - boost::unordered::detail::call_construct(alloc, ptr, \ + boost::unordered::detail::func::call_construct(alloc, ptr, \ BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ ); \ } @@ -945,7 +953,7 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) inline void construct_value_impl(Alloc& alloc, T* address, BOOST_FWD_REF(Args)... args) { - boost::unordered::detail::call_construct(alloc, + boost::unordered::detail::func::call_construct(alloc, address, boost::forward(args)...); } @@ -960,9 +968,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) construct_value_impl(Alloc& alloc, std::pair* address, BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - boost::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->first), boost::forward(a1)); - boost::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->second), boost::forward(a2)); } @@ -1032,19 +1040,15 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) boost::unordered::detail::emplace_args3 const& args, typename enable_if, void*>::type = 0) { - boost::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->first), args.a1); - boost::unordered::detail::construct_from_tuple(alloc, + boost::unordered::detail::func::construct_from_tuple(alloc, boost::addressof(address->second), args.a2); } #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES -}}} - -//////////////////////////////////////////////////////////////////////////////// -// -// Some helper functions for allocating & constructing +}}}} namespace boost { namespace unordered { namespace detail { diff --git a/cpp/BoostParts/boost/unordered/detail/buckets.hpp b/cpp/BoostParts/boost/unordered/detail/buckets.hpp index 65392241..95d8df18 100644 --- a/cpp/BoostParts/boost/unordered/detail/buckets.hpp +++ b/cpp/BoostParts/boost/unordered/detail/buckets.hpp @@ -32,6 +32,10 @@ namespace boost { namespace unordered { namespace detail { }}} +// The 'iterator_detail' namespace was a misguided attempt at avoiding ADL +// in the detail namespace. It didn't work because the template parameters +// were in detail. I'm not changing it at the moment to be safe. I might +// do in the future if I change the iterator types. namespace boost { namespace unordered { namespace iterator_detail { //////////////////////////////////////////////////////////////////////////// @@ -73,9 +77,9 @@ namespace boost { namespace unordered { namespace iterator_detail { typedef typename Node::value_type value_type; - l_iterator() : ptr_() {} + l_iterator() BOOST_NOEXCEPT : ptr_() {} - l_iterator(iterator x, std::size_t b, std::size_t c) + l_iterator(iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT : ptr_(x.node_), bucket_(b), bucket_count_(c) {} value_type& operator*() const { @@ -100,11 +104,11 @@ namespace boost { namespace unordered { namespace iterator_detail { return tmp; } - bool operator==(l_iterator x) const { + bool operator==(l_iterator x) const BOOST_NOEXCEPT { return ptr_ == x.ptr_; } - bool operator!=(l_iterator x) const { + bool operator!=(l_iterator x) const BOOST_NOEXCEPT { return ptr_ != x.ptr_; } }; @@ -132,13 +136,13 @@ namespace boost { namespace unordered { namespace iterator_detail { typedef typename Node::value_type value_type; - cl_iterator() : ptr_() {} + cl_iterator() BOOST_NOEXCEPT : ptr_() {} - cl_iterator(iterator x, std::size_t b, std::size_t c) : + cl_iterator(iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT : ptr_(x.node_), bucket_(b), bucket_count_(c) {} cl_iterator(boost::unordered::iterator_detail::l_iterator< - Node, Policy> const& x) : + Node, Policy> const& x) BOOST_NOEXCEPT : ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_) {} @@ -164,11 +168,15 @@ namespace boost { namespace unordered { namespace iterator_detail { return tmp; } - friend bool operator==(cl_iterator const& x, cl_iterator const& y) { + friend bool operator==(cl_iterator const& x, cl_iterator const& y) + BOOST_NOEXCEPT + { return x.ptr_ == y.ptr_; } - friend bool operator!=(cl_iterator const& x, cl_iterator const& y) { + friend bool operator!=(cl_iterator const& x, cl_iterator const& y) + BOOST_NOEXCEPT + { return x.ptr_ != y.ptr_; } }; @@ -204,9 +212,9 @@ namespace boost { namespace unordered { namespace iterator_detail { typedef typename Node::value_type value_type; - iterator() : node_() {} + iterator() BOOST_NOEXCEPT : node_() {} - explicit iterator(typename Node::link_pointer x) : + explicit iterator(typename Node::link_pointer x) BOOST_NOEXCEPT : node_(static_cast(x)) {} value_type& operator*() const { @@ -228,11 +236,11 @@ namespace boost { namespace unordered { namespace iterator_detail { return tmp; } - bool operator==(iterator const& x) const { + bool operator==(iterator const& x) const BOOST_NOEXCEPT { return node_ == x.node_; } - bool operator!=(iterator const& x) const { + bool operator!=(iterator const& x) const BOOST_NOEXCEPT { return node_ != x.node_; } }; @@ -266,12 +274,12 @@ namespace boost { namespace unordered { namespace iterator_detail { typedef typename Node::value_type value_type; - c_iterator() : node_() {} + c_iterator() BOOST_NOEXCEPT : node_() {} - explicit c_iterator(typename Node::link_pointer x) : + explicit c_iterator(typename Node::link_pointer x) BOOST_NOEXCEPT : node_(static_cast(x)) {} - c_iterator(iterator const& x) : node_(x.node_) {} + c_iterator(iterator const& x) BOOST_NOEXCEPT : node_(x.node_) {} value_type const& operator*() const { return node_->value(); @@ -292,11 +300,15 @@ namespace boost { namespace unordered { namespace iterator_detail { return tmp; } - friend bool operator==(c_iterator const& x, c_iterator const& y) { + friend bool operator==(c_iterator const& x, c_iterator const& y) + BOOST_NOEXCEPT + { return x.node_ == y.node_; } - friend bool operator!=(c_iterator const& x, c_iterator const& y) { + friend bool operator!=(c_iterator const& x, c_iterator const& y) + BOOST_NOEXCEPT + { return x.node_ != y.node_; } }; @@ -345,7 +357,7 @@ namespace boost { namespace unordered { namespace detail { void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS) { construct(); - boost::unordered::detail::construct_value_impl( + boost::unordered::detail::func::construct_value_impl( alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); value_constructed_ = true; } @@ -354,7 +366,7 @@ namespace boost { namespace unordered { namespace detail { void construct_with_value2(BOOST_FWD_REF(A0) a0) { construct(); - boost::unordered::detail::construct_value_impl( + boost::unordered::detail::func::construct_value_impl( alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward(a0))); value_constructed_ = true; @@ -384,7 +396,7 @@ namespace boost { namespace unordered { namespace detail { { if (node_) { if (value_constructed_) { - boost::unordered::detail::destroy_value_impl(alloc_, + boost::unordered::detail::func::destroy_value_impl(alloc_, node_->value_ptr()); } @@ -416,7 +428,7 @@ namespace boost { namespace unordered { namespace detail { if (value_constructed_) { - boost::unordered::detail::destroy_value_impl(alloc_, + boost::unordered::detail::func::destroy_value_impl(alloc_, node_->value_ptr()); value_constructed_ = false; } @@ -533,7 +545,7 @@ namespace boost { namespace unordered { namespace detail { node_pointer p = nodes_; nodes_ = static_cast(p->next_); - boost::unordered::detail::destroy_value_impl(this->alloc_, + boost::unordered::detail::func::destroy_value_impl(this->alloc_, p->value_ptr()); node_allocator_traits::destroy(this->alloc_, boost::addressof(*p)); node_allocator_traits::deallocate(this->alloc_, p, 1); @@ -715,20 +727,23 @@ namespace boost { namespace unordered { namespace detail { new((void*) &funcs_[which]) function_pair(hf, eq); } - void construct(bool which, function_pair const& f) + void construct(bool which, function_pair const& f, + boost::unordered::detail::false_type = + boost::unordered::detail::false_type()) { new((void*) &funcs_[which]) function_pair(f); } void construct(bool which, function_pair& f, - boost::unordered::detail::move_tag m) + boost::unordered::detail::true_type) { - new((void*) &funcs_[which]) function_pair(f, m); + new((void*) &funcs_[which]) function_pair(f, + boost::unordered::detail::move_tag()); } void destroy(bool which) { - boost::unordered::detail::destroy((function_pair*)(&funcs_[which])); + boost::unordered::detail::func::destroy((function_pair*)(&funcs_[which])); } public: @@ -748,15 +763,12 @@ namespace boost { namespace unordered { namespace detail { construct(current_, bf.current()); } - functions(functions& bf, boost::unordered::detail::move_tag m) + functions(functions& bf, boost::unordered::detail::move_tag) : current_(false) { - if (nothrow_move_constructible) { - construct(current_, bf.current(), m); - } - else { - construct(current_, bf.current()); - } + construct(current_, bf.current(), + boost::unordered::detail::integral_constant()); } ~functions() { diff --git a/cpp/BoostParts/boost/unordered/detail/extract_key.hpp b/cpp/BoostParts/boost/unordered/detail/extract_key.hpp index 60943d9b..92524b54 100644 --- a/cpp/BoostParts/boost/unordered/detail/extract_key.hpp +++ b/cpp/BoostParts/boost/unordered/detail/extract_key.hpp @@ -56,19 +56,19 @@ namespace detail { return no_key(); } -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - static no_key extract(Args const&...) - { - return no_key(); - } -#else template static no_key extract(Arg const&) { return no_key(); } +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + static no_key extract(Arg1 const&, Arg2 const&, Args const&...) + { + return no_key(); + } +#else template static no_key extract(Arg1 const&, Arg2 const&) { @@ -107,14 +107,6 @@ namespace detail { return k; } -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - static no_key extract(Args const&...) - { - return no_key(); - } -#else - static no_key extract() { return no_key(); @@ -126,8 +118,16 @@ namespace detail { return no_key(); } - template - static no_key extract(Arg const&, Arg1 const&) + template + static no_key extract(Arg1 const&, Arg2 const&) + { + return no_key(); + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + static no_key extract(Arg1 const&, Arg2 const&, Arg3 const&, + Args const&...) { return no_key(); } diff --git a/cpp/BoostParts/boost/unordered/detail/table.hpp b/cpp/BoostParts/boost/unordered/detail/table.hpp index 84d1183d..e848b21a 100644 --- a/cpp/BoostParts/boost/unordered/detail/table.hpp +++ b/cpp/BoostParts/boost/unordered/detail/table.hpp @@ -456,6 +456,8 @@ namespace boost { namespace unordered { namespace detail { void swap_allocators(table& other, false_type) { + boost::unordered::detail::func::ignore_unused_variable_warning(other); + // According to 23.2.1.8, if propagate_on_container_swap is // false the behaviour is undefined unless the allocators // are equal. @@ -514,7 +516,7 @@ namespace boost { namespace unordered { namespace detail { node_pointer n = static_cast(prev->next_); prev->next_ = n->next_; - boost::unordered::detail::destroy_value_impl(node_alloc(), + boost::unordered::detail::func::destroy_value_impl(node_alloc(), n->value_ptr()); node_allocator_traits::destroy(node_alloc(), boost::addressof(*n)); diff --git a/cpp/BoostParts/boost/unordered/detail/unique.hpp b/cpp/BoostParts/boost/unordered/detail/unique.hpp index 4ea071b2..81ac053e 100644 --- a/cpp/BoostParts/boost/unordered/detail/unique.hpp +++ b/cpp/BoostParts/boost/unordered/detail/unique.hpp @@ -334,8 +334,6 @@ namespace boost { namespace unordered { namespace detail { value_type& operator[](key_type const& k) { - typedef typename value_type::second_type mapped_type; - std::size_t key_hash = this->hash(k); iterator pos = this->find_node(key_hash, k); diff --git a/cpp/BoostParts/boost/unordered/detail/util.hpp b/cpp/BoostParts/boost/unordered/detail/util.hpp index a901477d..570cf8f8 100644 --- a/cpp/BoostParts/boost/unordered/detail/util.hpp +++ b/cpp/BoostParts/boost/unordered/detail/util.hpp @@ -28,6 +28,11 @@ namespace boost { namespace unordered { namespace detail { struct move_tag {}; struct empty_emplace {}; + namespace func { + template + inline void ignore_unused_variable_warning(T const&) {} + } + //////////////////////////////////////////////////////////////////////////// // iterator SFINAE diff --git a/cpp/BoostParts/boost/unordered/unordered_map.hpp b/cpp/BoostParts/boost/unordered/unordered_map.hpp index 682e3544..e33dcea2 100644 --- a/cpp/BoostParts/boost/unordered/unordered_map.hpp +++ b/cpp/BoostParts/boost/unordered/unordered_map.hpp @@ -117,11 +117,13 @@ namespace unordered #if defined(BOOST_UNORDERED_USE_MOVE) unordered_map(BOOST_RV_REF(unordered_map) other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) unordered_map(unordered_map&& other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } @@ -142,7 +144,7 @@ namespace unordered // Destructor - ~unordered_map(); + ~unordered_map() BOOST_NOEXCEPT; // Assign @@ -598,11 +600,13 @@ namespace unordered #if defined(BOOST_UNORDERED_USE_MOVE) unordered_multimap(BOOST_RV_REF(unordered_multimap) other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) unordered_multimap(unordered_multimap&& other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } @@ -623,7 +627,7 @@ namespace unordered // Destructor - ~unordered_multimap(); + ~unordered_multimap() BOOST_NOEXCEPT; // Assign @@ -1057,7 +1061,7 @@ namespace unordered } template - unordered_map::~unordered_map() {} + unordered_map::~unordered_map() BOOST_NOEXCEPT {} template unordered_map::unordered_map( @@ -1390,7 +1394,7 @@ namespace unordered } template - unordered_multimap::~unordered_multimap() {} + unordered_multimap::~unordered_multimap() BOOST_NOEXCEPT {} template unordered_multimap::unordered_multimap( diff --git a/cpp/BoostParts/boost/unordered/unordered_set.hpp b/cpp/BoostParts/boost/unordered/unordered_set.hpp index 0ccf1b94..9ba5002f 100644 --- a/cpp/BoostParts/boost/unordered/unordered_set.hpp +++ b/cpp/BoostParts/boost/unordered/unordered_set.hpp @@ -115,11 +115,13 @@ namespace unordered #if defined(BOOST_UNORDERED_USE_MOVE) unordered_set(BOOST_RV_REF(unordered_set) other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) unordered_set(unordered_set&& other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } @@ -140,7 +142,7 @@ namespace unordered // Destructor - ~unordered_set(); + ~unordered_set() BOOST_NOEXCEPT; // Assign @@ -582,11 +584,13 @@ namespace unordered #if defined(BOOST_UNORDERED_USE_MOVE) unordered_multiset(BOOST_RV_REF(unordered_multiset) other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) unordered_multiset(unordered_multiset&& other) + BOOST_NOEXCEPT_IF(table::nothrow_move_constructible) : table_(other.table_, boost::unordered::detail::move_tag()) { } @@ -607,7 +611,7 @@ namespace unordered // Destructor - ~unordered_multiset(); + ~unordered_multiset() BOOST_NOEXCEPT; // Assign @@ -1032,7 +1036,7 @@ namespace unordered } template - unordered_set::~unordered_set() {} + unordered_set::~unordered_set() BOOST_NOEXCEPT {} template unordered_set::unordered_set( @@ -1316,7 +1320,7 @@ namespace unordered } template - unordered_multiset::~unordered_multiset() {} + unordered_multiset::~unordered_multiset() BOOST_NOEXCEPT {} template unordered_multiset::unordered_multiset( diff --git a/cpp/BoostParts/boost/utility/base_from_member.hpp b/cpp/BoostParts/boost/utility/base_from_member.hpp index 04aabb59..e32ecb8d 100644 --- a/cpp/BoostParts/boost/utility/base_from_member.hpp +++ b/cpp/BoostParts/boost/utility/base_from_member.hpp @@ -1,6 +1,6 @@ // boost utility/base_from_member.hpp header file --------------------------// -// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and +// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and // distribution are subject to the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or a copy at // .) @@ -10,10 +10,15 @@ #ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP #define BOOST_UTILITY_BASE_FROM_MEMBER_HPP +#include #include #include #include #include +#include +#include +#include +#include // Base-from-member arity configuration macro ------------------------------// @@ -53,6 +58,59 @@ namespace boost { +namespace detail +{ + +// Type-unmarking class template -------------------------------------------// + +// Type-trait to get the raw type, i.e. the type without top-level reference nor +// cv-qualification, from a type expression. Mainly for function arguments, any +// reference part is stripped first. + +// Contributed by Daryle Walker + +template < typename T > +struct remove_cv_ref +{ + typedef typename ::boost::remove_cv::type>::type type; + +}; // boost::detail::remove_cv_ref + +// Unmarked-type comparison class template ---------------------------------// + +// Type-trait to check if two type expressions have the same raw type. + +// Contributed by Daryle Walker, based on a work-around by Luc Danton + +template < typename T, typename U > +struct is_related + : public ::boost::is_same< + typename ::boost::detail::remove_cv_ref::type, + typename ::boost::detail::remove_cv_ref::type > +{}; + +// Enable-if-on-unidentical-unmarked-type class template -------------------// + +// Enable-if on the first two type expressions NOT having the same raw type. + +// Contributed by Daryle Walker, based on a work-around by Luc Danton + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES +template +struct enable_if_unrelated + : public ::boost::enable_if_c +{}; + +template +struct enable_if_unrelated + : public ::boost::disable_if< ::boost::detail::is_related > +{}; +#endif + +} // namespace boost::detail + + // Base-from-member class template -----------------------------------------// // Helper to initialize a base object so a derived class can use this @@ -68,12 +126,25 @@ class base_from_member protected: MemberType member; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \ + !(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4)) + template ::type> + explicit BOOST_CONSTEXPR base_from_member( T&& ...x ) + BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType( + static_cast(x)... )) ) // no std::is_nothrow_constructible... + : member( static_cast(x)... ) // ...nor std::forward needed + {} +#else base_from_member() : member() {} BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY), BOOST_PRIVATE_CTR_DEF, _ ) +#endif }; // boost::base_from_member diff --git a/cpp/BoostParts/boost/utility/declval.hpp b/cpp/BoostParts/boost/utility/declval.hpp index d74610c5..a4ab2c8c 100644 --- a/cpp/BoostParts/boost/utility/declval.hpp +++ b/cpp/BoostParts/boost/utility/declval.hpp @@ -1,49 +1,44 @@ -// common_type.hpp ---------------------------------------------------------// +// declval.hpp -------------------------------------------------------------// // Copyright 2010 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP -#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#ifndef BOOST_UTILITY_DECLVAL_HPP +#define BOOST_UTILITY_DECLVAL_HPP #include //----------------------------------------------------------------------------// #include -//#include //----------------------------------------------------------------------------// // // // C++03 implementation of // +// 20.2.4 Function template declval [declval] // // Written by Vicente J. Botet Escriba // -//~ 20.3.4 Function template declval [declval] -//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as -//~ unevaluated operands. -//~ 2 Remarks: If this function is used, the program is ill-formed. -//~ 3 Remarks: The template parameter T of declval may be an incomplete type. -//~ [ Example: - -//~ template -//~ decltype(static_cast(declval())) convert(From&&); - -//~ declares a function template convert which only participats in overloading if the type From can be -//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). —end -//~ example ] // // +// 1 The library provides the function template declval to simplify the +// definition of expressions which occur as unevaluated operands. +// 2 Remarks: If this function is used, the program is ill-formed. +// 3 Remarks: The template parameter T of declval may be an incomplete type. +// [ Example: +// +// template +// decltype(static_cast(declval())) convert(From&&); +// +// declares a function template convert which only participates in overloading +// if the type From can be explicitly converted to type To. For another example +// see class template common_type (20.9.7.6). -end example ] //----------------------------------------------------------------------------// namespace boost { -//#if !defined(BOOST_NO_RVALUE_REFERENCES) template typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand -//#else -// template -// typename add_lvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand -//#endif + } // namespace boost -#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#endif // BOOST_UTILITY_DECLVAL_HPP diff --git a/cpp/BoostParts/boost/utility/detail/result_of_iterate.hpp b/cpp/BoostParts/boost/utility/detail/result_of_iterate.hpp index 17fd4d59..5192172c 100644 --- a/cpp/BoostParts/boost/utility/detail/result_of_iterate.hpp +++ b/cpp/BoostParts/boost/utility/detail/result_of_iterate.hpp @@ -38,10 +38,25 @@ struct tr1_result_of #endif #ifdef BOOST_RESULT_OF_USE_DECLTYPE - -// Uses declval following N3225 20.7.7.6 when F is not a pointer. template -struct result_of +struct result_of + : detail::cpp0x_result_of { }; +#endif // BOOST_RESULT_OF_USE_DECLTYPE + +#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK +template +struct result_of + : mpl::if_, detail::has_result >, + tr1_result_of, + detail::cpp0x_result_of >::type { }; +#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK + +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) + +namespace detail { + +template +struct cpp0x_result_of : mpl::if_< is_member_function_pointer , detail::tr1_result_of_impl< @@ -54,8 +69,6 @@ struct result_of >::type {}; -namespace detail { - #ifdef BOOST_NO_SFINAE_EXPR template @@ -139,7 +152,7 @@ struct cpp0x_result_of_impl diff --git a/cpp/BoostParts/boost/utility/result_of.hpp b/cpp/BoostParts/boost/utility/result_of.hpp index 97e96188..a530c3ac 100644 --- a/cpp/BoostParts/boost/utility/result_of.hpp +++ b/cpp/BoostParts/boost/utility/result_of.hpp @@ -38,18 +38,27 @@ // Use the decltype-based version of result_of by default if the compiler // supports N3276 . -// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or -// BOOST_RESULT_OF_USE_TR1, but not both! -#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1) -# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time. +// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE, +// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one! +#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \ + (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \ + (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) +# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \ + BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time. +#endif + +#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) +# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined. #endif #ifndef BOOST_RESULT_OF_USE_TR1 # ifndef BOOST_RESULT_OF_USE_DECLTYPE -# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) -# define BOOST_RESULT_OF_USE_DECLTYPE -# else -# define BOOST_RESULT_OF_USE_TR1 +# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK +# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE) +# define BOOST_RESULT_OF_USE_DECLTYPE +# else +# define BOOST_RESULT_OF_USE_TR1 +# endif # endif # endif #endif @@ -64,8 +73,12 @@ namespace detail { BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) +BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) + template struct tr1_result_of_impl; +template struct cpp0x_result_of; + #ifdef BOOST_NO_SFINAE_EXPR // There doesn't seem to be any other way to turn this off such that the presence of diff --git a/cpp/BoostParts/boost/version.hpp b/cpp/BoostParts/boost/version.hpp index d3826c2c..0df7b276 100644 --- a/cpp/BoostParts/boost/version.hpp +++ b/cpp/BoostParts/boost/version.hpp @@ -19,7 +19,7 @@ // BOOST_VERSION / 100 % 1000 is the minor version // BOOST_VERSION / 100000 is the major version -#define BOOST_VERSION 105400 +#define BOOST_VERSION 105500 // // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION @@ -27,6 +27,6 @@ // number, y is the minor version number, and z is the patch level if not 0. // This is used by to select which library version to link to. -#define BOOST_LIB_VERSION "1_54" +#define BOOST_LIB_VERSION "1_55" #endif diff --git a/cpp/BoostParts/libs/atomic/src/lockpool.cpp b/cpp/BoostParts/libs/atomic/src/lockpool.cpp index da8e89ad..1f11cce1 100644 --- a/cpp/BoostParts/libs/atomic/src/lockpool.cpp +++ b/cpp/BoostParts/libs/atomic/src/lockpool.cpp @@ -1,3 +1,5 @@ +#include +#include #include // Copyright (c) 2011 Helge Bahmann @@ -10,13 +12,42 @@ namespace boost { namespace atomics { namespace detail { -static lockpool::lock_type lock_pool_[41]; +namespace { + +// This seems to be the maximum across all modern CPUs +// NOTE: This constant is made as a macro because some compilers (gcc 4.4 for one) don't allow enums or regular constants in alignment attributes +#define BOOST_ATOMIC_CACHE_LINE_SIZE 64 + +template< unsigned int N > +struct padding +{ + char data[N]; +}; +template< > +struct padding< 0 > +{ +}; + +struct BOOST_ALIGNMENT(BOOST_ATOMIC_CACHE_LINE_SIZE) padded_lock +{ + lockpool::lock_type lock; + // The additional padding is needed to avoid false sharing between locks + enum { padding_size = (sizeof(lockpool::lock_type) <= BOOST_ATOMIC_CACHE_LINE_SIZE ? + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lockpool::lock_type)) : + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lockpool::lock_type) % BOOST_ATOMIC_CACHE_LINE_SIZE)) }; + padding< padding_size > pad; +}; + +static padded_lock lock_pool_[41]; + +} // namespace + // NOTE: This function must NOT be inline. Otherwise MSVC 9 will sometimes generate broken code for modulus operation which result in crashes. BOOST_ATOMIC_DECL lockpool::lock_type& lockpool::get_lock_for(const volatile void* addr) { std::size_t index = reinterpret_cast(addr) % (sizeof(lock_pool_) / sizeof(*lock_pool_)); - return lock_pool_[index]; + return lock_pool_[index].lock; } } diff --git a/cpp/BoostParts/libs/filesystem/src/operations.cpp b/cpp/BoostParts/libs/filesystem/src/operations.cpp index 16a336f6..a1504b55 100644 --- a/cpp/BoostParts/libs/filesystem/src/operations.cpp +++ b/cpp/BoostParts/libs/filesystem/src/operations.cpp @@ -73,13 +73,15 @@ using std::wstring; const fs::path dot_dot_path(".."); # include # include -# if !defined(__APPLE__) && !defined(__OpenBSD__) +# if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__) # include # define BOOST_STATVFS statvfs # define BOOST_STATVFS_F_FRSIZE vfs.f_frsize # else # ifdef __OpenBSD__ # include +# elif defined(__ANDROID__) +# include # endif # include # define BOOST_STATVFS statfs diff --git a/cpp/BoostParts/libs/system/src/error_code.cpp b/cpp/BoostParts/libs/system/src/error_code.cpp index cb1cb801..5e00588d 100644 --- a/cpp/BoostParts/libs/system/src/error_code.cpp +++ b/cpp/BoostParts/libs/system/src/error_code.cpp @@ -26,7 +26,9 @@ # if defined( BOOST_WINDOWS_API ) # include -# include "local_free_on_destruction.hpp" +# if !defined(WINAPI_FAMILY) || ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) != 0) +# include "local_free_on_destruction.hpp" +# endif # ifndef ERROR_INCORRECT_SIZE # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS # endif @@ -172,6 +174,17 @@ namespace using boost::system::errc::invalid_argument; #endif +# if defined(BOOST_WINDOWS_API) +# if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0) + // When using the Windows Runtime, most system errors are reported as HRESULTs. + // We want to map the common Win32 errors to their equivalent error condition, + // whether or not they are reported via an HRESULT. + if ( ev < 0 ) // Check for failed HRESULTs only. + if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 ) + ev = HRESULT_CODE( ev ); +# endif +# endif + switch ( ev ) { case 0: return make_error_condition( success ); @@ -359,7 +372,36 @@ namespace std::string system_error_category::message( int ev ) const { -# ifndef BOOST_NO_ANSI_APIS +# if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_DESKTOP) == 0) + std::string str( 128, char() ); + for (;;) + { + DWORD retval = ::FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + &str[0], + str.size(), + NULL + ); + + if ( retval > 0 ) + { + str.resize( retval ); + break; + } + else if ( ::GetLastError() != ERROR_INSUFFICIENT_BUFFER ) + { + return std::string("Unknown error"); + } + else + { + str.resize( str.size() + str.size()/2 ); + } + } +# elif !defined(BOOST_NO_ANSI_APIS) LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | diff --git a/cpp/BoostParts/libs/thread/src/pthread/thread.cpp b/cpp/BoostParts/libs/thread/src/pthread/thread.cpp index 96ef117a..bd67bae2 100644 --- a/cpp/BoostParts/libs/thread/src/pthread/thread.cpp +++ b/cpp/BoostParts/libs/thread/src/pthread/thread.cpp @@ -187,7 +187,9 @@ namespace boost return 0; } } - + } + namespace detail + { struct externally_launched_thread: detail::thread_data_base { @@ -197,7 +199,12 @@ namespace boost interrupt_enabled=false; #endif } - + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); + } void run() {} void notify_all_at_thread_exit(condition_variable*, mutex*) @@ -208,18 +215,18 @@ namespace boost void operator=(externally_launched_thread&); }; - detail::thread_data_base* make_external_thread_data() + thread_data_base* make_external_thread_data() { - detail::thread_data_base* const me(new externally_launched_thread()); + thread_data_base* const me(new externally_launched_thread()); me->self.reset(me); set_current_thread_data(me); return me; } - detail::thread_data_base* get_or_make_current_thread_data() + thread_data_base* get_or_make_current_thread_data() { - detail::thread_data_base* current_thread_data(detail::get_current_thread_data()); + thread_data_base* current_thread_data(get_current_thread_data()); if(!current_thread_data) { current_thread_data=make_external_thread_data(); @@ -701,8 +708,11 @@ namespace boost void erase_tss_node(void const* key) { - detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - current_thread_data->tss_data.erase(key); + detail::thread_data_base* const current_thread_data(get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->tss_data.erase(key); + } } void set_tss_data(void const* key, @@ -740,6 +750,17 @@ namespace boost current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); } } +namespace detail { + + void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr as) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->make_ready_at_thread_exit(as); + } + } +} diff --git a/cpp/BoostParts/libs/thread/src/win32/thread.cpp b/cpp/BoostParts/libs/thread/src/win32/thread.cpp index 28dd8d41..bc4a45ed 100644 --- a/cpp/BoostParts/libs/thread/src/win32/thread.cpp +++ b/cpp/BoostParts/libs/thread/src/win32/thread.cpp @@ -22,6 +22,7 @@ #include #include +#include #if defined BOOST_THREAD_USES_DATETIME #include #endif @@ -128,7 +129,7 @@ namespace boost return ret; } - typedef void* uintptr_t; + //typedef void* uintptr_t; inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr) @@ -278,6 +279,12 @@ namespace boost interruption_enabled=false; #endif } + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); + } void run() {} @@ -429,7 +436,7 @@ namespace boost LARGE_INTEGER due_time={{0,0}}; if(target_time.relative) { - unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start; + unsigned long const elapsed_milliseconds=detail::win32::GetTickCount64()-target_time.start; LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds); LONGLONG const hundred_nanoseconds_in_one_millisecond=10000; @@ -747,5 +754,16 @@ namespace boost current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); } } +//namespace detail { +// +// void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr as) +// { +// detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); +// if(current_thread_data) +// { +// current_thread_data->make_ready_at_thread_exit(as); +// } +// } +//} } diff --git a/update_boost.sh b/update_boost.sh index 5c59bcae..9fbc107a 100755 --- a/update_boost.sh +++ b/update_boost.sh @@ -14,7 +14,7 @@ fi pushd $1 ./bootstrap.sh -b2 tools/bcp +./b2 tools/bcp boost_part_dir=`mktemp -d -t boost_parts.XXXXXX`